Django——django1.6 基于类的通用视图
最初 django 的视图都是用函数实现的,后来开发出一些通用视图函数,以取代某些常见的重复性代码。通用视图就像是一些封装好的处理器,使用它们的时候只须要给出特定的参数集即可,不必关心具体的实现。各种通用视图的参考参见:https://docs.djangoproject.com/en/1.6/ref/class-based-views/
然 后函数式视图的缺点——难以扩展和自定义,开始显现出来。于是 1.3 起 django 开始用类视图来实现通用视图。较于函数,类能够更方便的实现继承和 mixins。但类视图并非要取代函数视图,这从现在 URLConf 仍然保留着函数式的调用方式便可以看出来。
因为 URLConf 仍然使用“给一个可调用对象传入 HttpRequest ,并期待其返回一个 HttpResponse”这样的逻辑,所以对于类视图,必须设计一个可调用的接口。这就是类视图的 as_view() 类方法。 他接受 request,并实例化类视图,接着调用实例的 dispatch() 方法。这个方法会依据 request 的请求类型再去调用实例的对应同名方法,并把 request 传过去,如果没有对应的方法,就引发一个 HttpResponseNotAllowed 异常。(可以捕捉这个异常用以返回一个 404)值得注意的是,这个(比如 get)方法的返回值和普通的视图函数的返回值没有什么不同,这意味着,http shortcuts(render_to_response之类的)和 TemplateResponse 在类视图里也是有效的。
django 提供了一系列现成的类视图,他们都继承自一个 View 基类(django.views.generic.base.View)。在这个基类里实现了与 URLs 的接口(as_view)、请求方法匹配(dispatch)和一些其他的基本功能。比如 RedirectView 实现了一个简单的 HTTP 重定向,TemplateView 给 View 添加了一个渲染模板的功能。
简单用法:
最简单的通用视图用法就是直接在 URLConf 里创建他们。如果你只需要改几个类视图的属性的话,你可以直接把他们当做关键字参数传入视图的 as_view() 方法里。任何传入 as_view() 的参数都会覆盖类视图实例里的同名属性。
子类化通用视图:
一种稍微高级点的使用通用视图的方法是子类化他们,并重写必要的属性(比如 template_name)和方法(比如 get_context_data)。举个栗子,一个 AboutView,他覆盖了 TemplateView 的模板属性和获取 Context 方法(这是使用 TemplateView 的一般做法):
对应的 URLConf:
这里的 get_context_data(self,**kwargs) 方法只接受关键字参数,是因为这个参数来自于 URLConf 的第三个参数(这例子里没用到),而这个参数就是一个关键字参数。
另外,如果想要对 context 做某些额外的处理,比如增加一些变量,那么就应该把代码写在调用了父类的 get_context_data 之后,return context 之前。
上面这个例子对通用视图的好处体现的还不明显(TemplateView 比 render_to_response 强不到哪去),通用视图的优势常常体现在对数据库的访问上,比如下面这个 显示对象列表的视图,完全省去了对数据库的操作:
ListView 会用到的模板:
template contexts 的变量名匹配:
上例中,在 publisher_list.html 模板中使用的 context 变量名为“object_list”。这是一个通用名,即 ListView 视图总会使用的一个名字,另外当你访问的是一个数据库模型的时候,比如上例中的 Publisher,视图还会自动用小写的模型名+_list 的格式命名一个相同的 context 去渲染模板,即“publisher_list”。所以上例中和其他对模型的访问都可以用这种格式的名字来编写模板。如果对此种匹配方式仍不放心,还可以 在通用视图中显式指定 context 的名字,就像这样(建议总是显示指定):
对数据模型进行筛选:
通过 model = Publisher 这样的方式可以指定通用视图使用的模型,而当想要对模型的 objects 管理器应用 filter 的时候,可以通过 query_set 变量来指定:
而如果 filter 的参数来自于 url 匹配出的子组,那么这个参数将被传入类视图的 self.args 和 self.kwargs 属性内。get_queryset() 方法也可以用来做逻辑性更强的定制:
实现模型访问时的额外小动作:
如果想要在对数据库进行访问之前(或后)实现一些额外的操作,那么可以通过封装 类视图的 get_object() 方法来实现。
例:假设 Author 模型有一个 DateTimeField 类型的字段,名为 last_accessed,用以保存最后一次被访问的时间。
此处 URL 里的 pk 是 DetailView 视图默认使用的某个名字,详情可参考视图的细节页面。
对 HTTP require method 的支持:
为不同的请求写一个同名的方法就可以了,调用工作会有 dispatch() 方法来做。比如:
还可以定义一些 head() , post() 之类的方法。这种方式取代了视图函数里的 if 分支逻辑。
处理 Form:
基本 Forms:
一个简单的 contact form
对应的视图可以使用 FormView 构建:
注意:
- FormView 继承自 TemplateResponseMixin,所以 template_name 属性可用
- form_valid() 的默认实现仅仅是将页面重定向至 success_url
Django——django1.6 基于类的通用视图的更多相关文章
- Django 1.6 基于类的通用视图
Django 1.6 基于类的通用视图 最初 django 的视图都是用函数实现的,后来开发出一些通用视图函数,以取代某些常见的重复性代码.通用视图就像是一些封装好的处理器,使用它们的时候只须要给出特 ...
- Django 基于类的通用视图
在早期,我们认识到在视图开发过程中有共同的用法和模式.这时我们引入基于函数的通用视图来抽象这些模式以简化常见情形的视图开发. 基于函数视图的用法有以下三种: def index(request): r ...
- 用基于类的通用视图处理表单(Class-based generic views)
处理表单通常包含3步: 初始化GET(空白的后者预填充的表单) POST非法数据(通常重新显示带有错误信息的表单) POST合法数据(提交数据并重定向) 为了将你从这些烦人的重复步骤中解救出来,Dja ...
- 基于类的通用视图(Class-based generic views)
在web开发中,最令人头痛的就是一遍又一遍的重复固定的模式.在解决了模板层面和模型层面的重复代码之痛之后,Django使用通用视图来解决视图层面的代码重复. 扩展通用视图 毫无疑问通用视图可以大幅度地 ...
- Django:之Sitemap站点地图、通用视图和上下文渲染器
Django中自带了sitemap框架,用来生成xml文件 Django sitemap演示: sitemap很重要,可以用来通知搜索引擎页面的地址,页面的重要性,帮助站点得到比较好的收录. 开启si ...
- Django初级手册4-表单与通用视图
表单的编写 1. detail.html模版的编写 <h1>{{ poll.question }}</h1> {% if error_message %}<p>&l ...
- Django——基于类的视图(class-based view)
刚开始的时候,django只有基于函数的视图(Function-based views).为了解决开发视图中繁杂的重复代码,基于函数的通用视图( Funcation-based generic vie ...
- django通用视图(类方法)
这周是我入职的第一周,入职第一天看到嘉兴大佬的项目代码.视图中有类方法,我感到很困惑. 联想到之前北京融360的电话面试,问我有无写过类方法……看来有必要了解下视图的类方法,上网搜了很多,原来这就是所 ...
- 介绍——基于类的视图(class-based view)
刚开始的时候,django只有基于函数的视图(Function-based views).为了解决开发视图中繁杂的重复代码,基于函数的通用视图( Class-based generic views) ...
随机推荐
- 用IJ和gradle启动elasticsearch5.4.3
环境准备 jdk gradle3.3+ idea git 从git clone源码 git checkout v5.4.3 打开项目 1. 在edit configurations添加new conf ...
- kafka consumer 代码示例
使用者小组 使得许多进程的多台机器 在逻辑上作为一个单个的使用者 出现. 我们使用中,一种常见的情况是,我们按照逻辑划分出多个使用者小组,每个小组都是有作为一个逻辑整体的多台使用者计算机组成的集群. ...
- python3生成测试数据,并写入ssdb
import pyssdb import random import time c = pyssdb.Client() chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoP ...
- CodeFirst模式开发涉及到mysql简单使用
在和同学写自己的小项目中,这次大胆的用到了“mysql”,毕竟是第一次在项目中使用,可我和同学就犯难了,我们没有真正意义上学过mysql,或者可以说,使用过mysql,当我们把项目放在www.git. ...
- python3爬虫爬取煎蛋网妹纸图片(下篇)2018.6.25有效
分析完了真实图片链接地址,下面要做的就是写代码去实现了.想直接看源代码的可以点击这里 大致思路是:获取一个页面的的html---->使用正则表达式提取出图片hash值并进行base64解码--- ...
- 51nod 编辑距离问题(动态规划)
编辑距离问题 给定两个字符串S和T,对于T我们允许三种操作:(1) 在任意位置添加任意字符(2) 删除存在的任意字符(3) 修改任意字符 问最少操作多少次可以把字符串T变成S? 例如: S= “AB ...
- 27、Django实战第27天:全局搜索功能开发
当我们选择其中一个类别(公开课,课程讲师,授课老师),输入搜索内容,点击搜索后会跳转到相应的列表页中进行展示 我们输入的内容作为参数keyword传入后台 搜索"公开课" 当课程中 ...
- 【单调队列】bzoj1047 [HAOI2007]理想的正方形
先把整个矩阵处理成b[n][m-K+1].c[n][m-K+1]大小的两个矩阵,分别存储每行每K个数中的最大.最小值,然后再通过b.c处理出d.e分别表示K*K大小的子矩阵中的最大.最小值即可.单调队 ...
- 【暴力】【推导】bzoj1088 [SCOI2005]扫雷Mine
考虑右侧的一个格子是否放雷,只可能对其左侧的三个格子造成影响. 也就是说,若左侧一个格子旁的两个格子已经放了雷,对第三个格子也就唯一确定了. 因此只枚举前两个格子是否放雷,剩下的暴力判断是否合法即可. ...
- python基础-文件处理与函数
1. 文件处理 1.1 文件处理流程 1.打开文件,得到文件句柄并赋值给一个变量 2.通过句柄对文件进行操作 3.关闭文件 1.2 文件读取模式r r文本模式的读,在文件不存在,不会创建新文件 f = ...