Django通用视图
Contents
使用通用视图的好处在于,能够最大程度的重复利用代码,减少代码量,并且方便扩展。
使用 函数 的方式实现:
|
|
使用 通用视图 的方式实现:
|
|
从上面的代码可以看到,使用 通用视图的方式实现时,只需要指定极少的参数即可实现相同的功能。不用自己完成数据的读取,不用自己设置模型的上下文,不用自己渲染模板。
通用视图
Django类视图的源码位于 django.views.generic 包中,其目录结构如下:
|
|
各模块的功能如下:
- base.py - 主要存放所有类视图的基类 View ,以及一些和数据库操作无关的类视图如 TemplateView、RedirectView。
- dates.py - 主要存放用于按时间归档的类视图,如 ArchiveIndexView,一些视图在博客系统中非常有用,例如获取某个日期下的全部文章列表。
- detail.py - 主要存放用于从数据库获取单条记录的类视图,例如从数据库中获取某一篇博客文章。
- edit.py - 主要包含了表单处理,创建、更新和删除数据库中的单条记录的类视图。
- list.py - 主要包含了从数据库中获取多条记录的类视图,例如从数据库中获取全部博客文章列表。
让人惊喜的是,虽然 Django中类视图种类繁多,而且继承关系复杂,但是耐下性子来分析,会发现他们条理很清晰,各个类只负责自己所关心的事情,并且命名也严格遵循一定的规则。
例如 ListView 视图的继承关系如下:
|
|
DetailView 视图的继承关系乳腺癌:
|
|
下面单从 ListView 视图从源码角度分析具体的实现。
ListView
ListView继承自 MultipleObjectTemplateResponseMixin、BaseListView两个父类,具体功能都由对应的父类完成。
|
|
MultipleObjectTemplateResponseMixin
MultipleObjectTemplateResponseMixin类定义了一个变量参数 template_name_suffix,表示的是模板名称的后缀。
重写了父类 TemplateResponseMixin 的 get_template_names获取模板名称函数。
- 如果父类 TemplateResponseMixin中的变量 template_name 未赋值,则会根据参数在模板列表中添加 app名称+模块名+模板名称后缀.html 为模板名的模板文件名。
- 如果父类 TemplateResponseMixin中的变量 template_name 有赋值,则会追加上述命名方式的模板文件。
|
|
TemplateResponseMixin
TemplateResponseMixin类的作用是混合不同预设参数,渲染模板后返回。
类中的变量有:
- template_name - 用户指定的模板名称,默认为None。
- template_engine - 用户指定的模板引擎,默认为None。
- response_class - 定义返回函数,默认为 TemplateResponse。
- content_type - 定义返回类型,默认为None。
类中的功能函数有:
- render_to_response - 根据上下文,指定的模板引擎等,返回渲染后的模板。
- get_template_names - 返回模板名称列表,用户未指定 template_name 时,返回异常,由子类捕获后,添加默认的模板名称列表。
|
|
BaseListView
BaseListView类继承自 MultipleObjectMixin, View类。
BaseListView类只实现了 get请求,会查询model中是否含有数据,如果 allow_empty参数设置为False,并且数据为空,则会返回404页面。最后的返回由绑定了的 TemplateResponseMixin类中的 render_to_response函数处理。
|
|
MultipleObjectMixin
MultipleObjectMixin类的作用是混合了用户自定义的多个对象。
类中定义的变量参数有:
- allow_empty - 是否允许数据为空,默认为True。
- queryset - 用于存储查询对象,类型可以为任意 iterable对象,默认为None。
- model - 指定模型的名称,如果 queryset参数用户未指定,则会从指定的模型中读取数据,默认为None。
- paginate_by - 分页,指定每页的大小,默认为None。
- paginate_orphans - 返回分页时扩展最后一页的最大孤儿项目数量,默认为0。
- context_object_name - 取出的模型数据在上下文中的名称,该名称用于渲染时传入模板,默认为None时,会根据一定的规则生成。
- paginator_class - 分页处理类,默认为 Paginator。
- page_kwarg - 分页名称参数,默认为 ‘page’。
- ordering - 排序标准,定义了model变量后,可以根据model中的字段名来排序。
实现的功能函数有:
- get_queryset - 返回该视图的数据队列,如果设置了排序选项,会返回排序后的数据。
- get_ordering - 返回 ordering。
- paginate_queryset - 返回分页化后的数据,输入参数: queryset输入数据, page_size每页数据量。
- get_paginate_by - 返回 paginate_by。
- get_paginator - 返回分页处理类的实例。
- get_paginate_orphans - 返回 paginate_orphans。
- get_allow_empty - 返回 allow_empty。
- get_context_object_name - 返回model在上下文中的名称。
- get_context_data - 返回上下文。
|
|
ContextMixin
ContextMixin类包括了一个变量 extra_context表示额外的上下文变量。一个功能函数 get_context_data,在上下文中添加了 **‘view’**代表自身,如果有额外的上下文,也添加。
|
|
View
View类是所有 视图类的基类,它只实现了http请求方法的调度和简单的参数检查。
类中参数 http_method_names记录了所有允许的http请求类型。
实现的功能函数有:
- as_view - 在函数内部定义了 view,当执行 as_view时,会返回该函数,作为可执行对象。
- dispatch - http请求分发函数,会在子类中查找对应的请求属性,例如 BaseListView中只实现了 get请求方法,则 BaseListView只响应get请求。
- http_method_not_allowed - 如果请求方法不在规定的方法内,则返回 HttpResponseNotAllowed对象实例。
- options - 返回视图允许的请求类型。
- _allowed_methods - 返回视图允许的请求类型。
|
|
使用通用视图
在使用通用视图替换原来的函数实现后,要将 urls.py中的路由映射修改:
|
|
使用 **as_view()**方法替换原来的视图函数,如上面分析, **as_view()**函数调用后会返回一个 view方法供调用。
总结
Django中的通用视图还有很多,如
|
|
熟悉使用通用视图会加快开发速度!