上一篇我们粗略介绍了Django中的class-based view基础知识, 本篇我们继续来看关于class-based view的高级应用.
我们继续沿用上篇中的model:
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()
|
我们来看看如何对一个Book实例进行更新, 我们要做的只是在视图类中更新 :
from django.views.generic.edit import UpdateView from models import Book from forms import BookForm class UpdateBook(UpdateView): form_class = BookForm model = Book template_name = 'updatebook.html'
|
但是, 我们很多时候并不是简单地对一个实例进行如上的更新, 可能有更复杂的要求, 比如想隐藏一些属性让用户更新时不可见, 甚至有些属性(比如用户)都是在针对当前登录用户进行操作的, 而不用手动选择哪个用户, 类似这样的操作应该如何实现呢? 我们不妨把Book Model修改一下:
from django.contrib.auth.models import User class Book(models.Model): title = models.CharField(max_length=100) author = models.ForeignKey(User, related_name='Author') publisher = models.ForeignKey(Publisher) publication_date = models.DateField()
|
我们把author改成User, 并使用ForeignKey关联. 下面将要实现针对当前登录用户增加一个Book实例, 重写AddBookForm如下:
from django import forms from django.contrib.auth.models import User from models import Book class AddBookForm(forms.ModelForm): class Meta: model = Book exclude = ('author',) def __init__(self, user, *args, **kwargs): super(AddBookForm, self).__init__(*args, **kwargs) self.fields['author'].queryset = User.objects.get(username = user.username)
|
下面来看视图类:
from django.views.generic.edit import UpdateView from models import Book from forms import AddBookForm class UpdateBook(UpdateView): form_class = AddBookForm model = Book template_name = 'updatebook.html' def get_object(self): return Snippet(author = self.request.user) def get_form(self, form_class): return self.form_class(self.request.user, **self.get_form_kwargs())
|
经过简单地变化, 我们就可以在不用选择author而使用当前登录用户替代来实现创建Book.
值得注意的是get_object这个方法, 它继承自SingleObjectMixin, 如果你需要更复杂的对单实例的操作, 只需在你的视图中按照你的逻辑重写这个方法就可以了! 是不是简化了不少呢? 其他的class-based view实现都和这个类似, 可以说Form类操作是Django类视图中的典型.
总结
根据以上的讨论, 我们可以得出一个结论: 任何视图操作都可以用类视图之间的聚合, 方法重写完成你想要的操作!(包括AJAX, 在Django官方文档中给出了一个简单的示例, 如果你有兴趣, 可以用它来做实验.) 但是有一点比较遗憾: 由于Django1.3刚刚发布不久, 还没有成熟的网站用到class-based view来实现全部的视图操作, 性能方面还有待考验. 后续的Django关于AJAX的应用下篇细说!
上一篇:16 个 Sublime Text 快捷键
下一篇:Django class-based view 基础