用基于类的通用视图处理表单(Class-based generic views)
处理表单通常包含3步:
初始化GET(空白的后者预填充的表单)
POST非法数据(通常重新显示带有错误信息的表单)
POST合法数据(提交数据并重定向)
为了将你从这些烦人的重复步骤中解救出来,Django为表单提供了一类通用视图
基础表单
这是一个简单的联系表单:
|
1
2
3
4
5
6
7
8
9
10
|
# forms.pyfrom django import formsclass ContactForm(forms.Form): name = forms.CharField() message = forms.CharField(widget=forms.Textarea) def send_email(self): # send email using the self.cleaned_data dictionary pass |
视图用FormView来构造:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# views.pyfrom myapp.forms import ContactFormfrom django.views.generic.edit import FormViewclass ContactView(FormView): template_name = 'contact.html' form_class = ContactForm success_url = '/thanks/' def form_valid(self, form): # This method is called when valid form data has been POSTed. # It should return an HttpResponse. form.send_email() return super(ContactView, self).form_valid(form) |
注意:
FormView是从TemplateResponseMixin来的,所以可以使用template_name
默认的form_valid()只是简单的重定向到success_url
模型表单
在处理模型的时候,通用视图才能大显身手。只要可以找到要处理的模型类,这些通用视图会自动创建ModelForm:
如果指明了model属性,那个模型类将被选择
如果get_object()返回了一个对象,那个对象的类将会被选择
如果指明了queryset,相关的模型将会被选择
模型表单视图提供form_valid()方法来自动保存模型。如果有特殊需要,你可以重写它,看下面的例子
你甚至不必为CreateView和UpdateView指明success_url,他们会自动选择模型对象中的get_absolute_url()(如果存在的话)。你也可以简单地设置form_class来定制一个ModelForm(为模型添加额外的验证)
注意当指定一个定制的表单类时,你也必须指定模型,尽管form_class可能就是一个ModelForm
首先我们需要添加为Author类添加get_absolute_url()
|
1
2
3
4
5
6
7
8
9
|
# models.pyfrom django.core.urlresolvers import reversefrom django.db import modelsclass Author(models.Model): name = models.CharField(max_length=200) def get_absolute_url(self): return reverse('author-detail', kwargs={'pk': self.pk}) |
然后我们使用CreateView和它的朋友们来做实际的工作。注意我们在这里如何匹配基于类的通用视图,我们不必写任何的逻辑代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# views.pyfrom django.views.generic.edit import CreateView, UpdateView, DeleteViewfrom django.core.urlresolvers import reverse_lazyfrom myapp.models import Authorclass AuthorCreate(CreateView): model = Authorclass AuthorUpdate(UpdateView): model = Authorclass AuthorDelete(DeleteView): model = Author success_url = reverse_lazy('author-list') |
注意:这里必须要用reverse_lazy(),而不仅仅是reverse,因为当文件被导入时urls没有被加载
最后,我们在URLconf中加上这些新的视图:
|
1
2
3
4
5
6
7
8
9
10
|
# urls.pyfrom django.conf.urls import patterns, urlfrom myapp.views import AuthorCreate, AuthorUpdate, AuthorDeleteurlpatterns = patterns('', # ... url(r'author/add/$', AuthorCreate.as_view(), name='author_add'), url(r'author/(?P<pk>\d+)/$', AuthorUpdate.as_view(), name='author_update'), url(r'author/(?P<pk>\d+)/delete/$', AuthorDelete.as_view(), name='author_delete'),) |
注意:这些视图都继承于SingleObjectTemplateMinxin,这个类使用template_name_suffix来构造基于模型的template_name
在这个例子中:
CreateView和UpdateView使用myapp/author_form.html
DeleteView使用myapp/author_confirm_date.html
如果你想要为CreateView和UpdateView使用不同的模板,你可以在你的视图类里设置template_name或者template_name_suffix
模型和request.user
为了跟踪用户使用CreateView创建对象,你可以使用定制的ModelForm来实现它。
首先,为模型增加外键:
|
1
2
3
4
5
6
7
8
9
|
# models.pyfrom django.contrib.auth import Userfrom django.db import modelsclass Author(models.Model): name = models.CharField(max_length=200) created_by = models.ForeignKey(User) # ... |
创建一个定制的ModelForm来隔离created_by,以免用户去编辑它:
|
1
2
3
4
5
6
7
8
|
# forms.pyfrom django import formsfrom myapp.models import Authorclass AuthorForm(forms.ModelForm): class Meta: model = Author exclude = ('created_by',) |
在这个视图中,使用定制的form_class并重写form_valid()来增加user:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
# views.pyfrom django.views.generic.edit import CreateViewfrom myapp.models import Authorfrom myapp.forms import AuthorFormclass AuthorCreate(CreateView): form_class = AuthorForm model = Author def form_valid(self, form): form.instance.created_by = self.request.user return super(AuthorCreate, self).form_valid(form) |
注意你需要使用login_required()来装饰这个视图,或者在form_valid()里处理未登录的用户
AJAX例子
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
import jsonfrom django.http import HttpResponsefrom django.views.generic.edit import CreateViewclass AjaxableResponseMixin(object): """ Mixin to add AJAX support to a form. Must be used with an object-based FormView (e.g. CreateView) """ def render_to_json_response(self, context, **response_kwargs): data = json.dumps(context) response_kwargs['content_type'] = 'application/json' return HttpResponse(data, **response_kwargs) def form_invalid(self, form): response = super(AjaxableResponseMixin, self).form_invalid(form) if self.request.is_ajax(): return self.render_to_json_response(form.errors, status=400) else: return response def form_valid(self, form): # We make sure to call the parent's form_valid() method because # it might do some processing (in the case of CreateView, it will # call form.save() for example). response = super(AjaxableResponseMixin, self).form_valid(form) if self.request.is_ajax(): data = { 'pk': self.object.pk, } return self.render_to_json_response(data) else: return responseclass AuthorCreate(AjaxableResponseMixin, CreateView): model = Author |
转载请注明出处
用基于类的通用视图处理表单(Class-based generic views)的更多相关文章
- Django 基于类的通用视图
在早期,我们认识到在视图开发过程中有共同的用法和模式.这时我们引入基于函数的通用视图来抽象这些模式以简化常见情形的视图开发. 基于函数视图的用法有以下三种: def index(request): r ...
- Django 1.6 基于类的通用视图
Django 1.6 基于类的通用视图 最初 django 的视图都是用函数实现的,后来开发出一些通用视图函数,以取代某些常见的重复性代码.通用视图就像是一些封装好的处理器,使用它们的时候只须要给出特 ...
- Django——django1.6 基于类的通用视图
最初 django 的视图都是用函数实现的,后来开发出一些通用视图函数,以取代某些常见的重复性代码.通用视图就像是一些封装好的处理器,使用它们的时候只须要给出特定的参数集即可,不必关心具体的实现.各种 ...
- 基于类的通用视图(Class-based generic views)
在web开发中,最令人头痛的就是一遍又一遍的重复固定的模式.在解决了模板层面和模型层面的重复代码之痛之后,Django使用通用视图来解决视图层面的代码重复. 扩展通用视图 毫无疑问通用视图可以大幅度地 ...
- 基于jQuery会员中心安全修改表单代码
基于jQuery会员中心安全修改表单代码.这是一款登录密码,交易密码,手机号码,实名认证,电子邮箱,安全设置表单,会员表单等设置代码.效果图如下: 在线预览 源码下载 实现的代码. html代码: ...
- 一款基于jquery ui的动画提交表单
今天要给大家分享一款基于jquery ui的动画提交表单.这款提交表单的的效果是以动画的形式依次列表所需填写的信息.效果非常不错,效果图如下: 在线预览 源码下载 实现的代码. html代码: & ...
- YII用户注冊和用户登录(二)之登录和注冊在视图通过表单使用YII小物件并分析
2 登录和注冊在视图通过表单使用YII小物件并分析 <?php $form = $this -> beginWidget('CActiveForm', array( 'enableClie ...
- Laravel 5 基础(十一)- 子视图和表单复用
我们需要处理编辑文章的问题.当然我们可以手工添加新的路由,就像这样: Route::get('/articles/{id}/edit', 'ArticleController@edit'); 让我们在 ...
- 【表单验证】基于jQuery的高度灵活的表单验证(无UI)
表单验证是前端开发过程中常见的一个需求,产品需求.业务逻辑的不同,表单验证的方式方法也有所区别.而最重要的是我们要清楚,表单验证的核心原则是--错误信息提示准确,并且尽可能少的打扰/干扰用户的输入和体 ...
随机推荐
- ./vi: line 2: mkdir: command not found
当前两天博主在写脚本的时候,运行脚本时候总是出现此消息,很郁闷, 开始我以为可能是我mkdir的函数库依赖的问题,但是当我用其他的脚本创建 目录的时候,命令又可以用了,找了半天,终于找到了答案 --- ...
- 通过IIS共享文件夹来实现静态资源"本地分布式"部署
以下以文件型数据库(如sqlite)为例 楼主话:以下内容,若有不专业处,大胆喷,虚心求教. 起因:要进行一个项目的分布式部署,而这个项目所涉及的其中一个数据库为sqlite(经测试,同为文件型数据库 ...
- scala高级性质-隐式转换 -02
今天我们来介绍scala的高级特性,上次已经介绍过他的一个特性:高阶函数,这次是隐式转换 1.隐式转换的例子 read的例子 解析:发现这个file没有read的方法,然后就开始在开始在这个上下文里面 ...
- Android面试收集录12 View测量、布局及绘制原理
一.View绘制的流程框架 View的绘制是从上往下一层层迭代下来的.DecorView-->ViewGroup(--->ViewGroup)-->View ,按照这个流程从上往下, ...
- 4,版本控制git --忽略特殊文件
有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...,有强迫症的童鞋心里肯定 ...
- 原码、反码、补码、BCD码、格雷码
二进制的最高位表示这个二进制的正负符号(0为正,1为负),其余各位数表示其数值本身称为原码. 正数的反码等于原码,负数的反码是在原码的基础上,符号位不变,其余各位取反. 正数的补码等于原码,负数的补码 ...
- Column 'sort' specified twice错误
我使用的是mybatis框架出现的这个问题,如果你们也出现了这个问题的豪华,我想你们的sql代码一定是复制的吧,额哈哈哈
- Tomcat详解及SNS系统的部署实现
Tomcat详解及SNS系统的部署实现 http://jungege.blog.51cto.com/4102814/1409290
- Docker应用设计四大关键
TechTarget中国原创] Docker已经垄断了容器技术.设计应用时注意考虑便携性能够帮助企业利用容器技术能提供的所有优势. 随着Docker应用和容器越来越流行,很多公司都开始将容器技术作为其 ...
- Tensorflor实现文本分类
Tensorflor实现文本分类 下面我们使用CNN做文本分类 cnn实现文本分类的原理 下图展示了如何使用cnn进行句子分类.输入是一个句子,为了使其可以进行卷积,首先需要将其转化为向量表示,通常使 ...