自从Django在1.3中新增了class-based view以来,还没有仔细研究它,开始感觉这个东西是否有点多余?因为Django已经有了Generic veiws了啊, 可是仔细看过class-based veiw之后, 这种想法打消了, 因为你完全可以用类方法实现你所有的视图, 而代码阅读起来却更容易!
如果要深入理解class-based view, 那首先就要了解什么是Mixin! Django把基本的http请求和响应抽象出来, 封装成各自的类, 在使用过程中只需把各个基类聚合到一起使用, 并按照自己的要求重写自己需要的方法就可以了, 那么就把这些基类叫Mixin吧. 在Django中比较基础的Mixin主要有几类:
- View(视图基础类)
- SingleObjectMixin(单对象类)
- MultipleObjectMixin(多对象类)
- TemplateResponseMixin(模板响应类)
- FormMixin(表单类)
- YearMixin, MonthMixin, DayMixin, WeekMixin, DateMixin(几个基于时间关系的类)
其他的所有内置class-based view都是把以上几个基础类组合, 重写方法以达到预期的结果. 比如DetailView这个类就组合了SingleObjectTemplateResponseMixin和BaseDetailView. 而在Django官方文档中有比较详细的ListView和DetailView的详细例子和说明, 本文这里就不在重复了, 本文的目的主要集中在官方文档中没有仔细说明的FormMixin上,下面来看例子, 我们就用官网上提供的models:
from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() class Meta: ordering = ["-name"] def __unicode__(self): return self.name class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField('Author') publisher = models.ForeignKey(Publisher) publication_date = models.DateField()
|
这个model中提供了2个类, 一个是Publisher, 一个是Book. 下面来看如何用FormMixin更新Book:
首先, 我们需要创建一个form, 代码如下:
from django import forms from models import Book class BookForm(forms.ModelForm): class Meta: model = Book
|
那么在我们的视图类就可以简单地这样来操作:
from django.views.generic.edit import CreateView from models import Book from forms import BookForm class AddBook(CreateView): form_class = BookForm model = Book template_name = 'addbook.html'
|
接着我们创建这个模板文件, 比如:
<form action="/contact/" method="post">{% csrf_token %} {{ form.as_p }} <input type="submit" value="Submit" /> </form>
|
最后一步就是在urls文件中指向我们创建的AddBook类了, 例如:
url(r'^createbook/$', AddBook.as_view(), name = 'createbook'),
|
完成以上的步骤就可以创建Book了! 简单吧? 好像还有点问题, 怎么非登陆用户也能创建Book? 这个问题我们可以参照Django官方文档中的例子, 我们可以给AddBook类添加一个方法,如下:
from django.views.generic.edit import CreateView from django.contrib.auth.decorators import login_required from django.utils.decorators import method_decorator from models import Book from forms import BookForm class AddBook(CreateView): form_class = BookForm model = Book template_name = 'addbook.html' @method_decorator(login_required) def dispatch(self, *args, **kwargs): return super(ProtectedView, self).dispatch(*args, **kwargs)
|
这样, 当用户想要创建Book而又没有登陆的话, 浏览器会跳转到登陆界面.
写了这么点就感觉有点乱了, 整理一下, 明天继续写FormMixin应用的深入应用.
上一篇:Django class-based view 深入