Django 之 基于类的视图源码分析

基于类的视图(Class-based view)是Django 1.3引入的新的视图编写方式,用于取代之前基于函数(Function-based)方式。 借助于OO和Python中方便的多重继承特性,基于类的视图能够提供更好的抽象与复用能力。 新的通用视图将更加优雅。 html

Django的文档较为丰富,但在实际开发中每每仍显得不够,不少时候仍是须要深刻到源代码当中一探究竟。为此,仔细整理了一下基于类的视图的实现方式。指望对之后的开发可以提供更加清晰、直接的参考。 算法

说明: Django大量应用了多重继承特性。将一些通用的功能性代码拆分混入类(Mixin),须要这些混入类的代码时,只须要将混入类加入到类的继承列表中便可——请注意顺序,左侧的类具备较高权限,将覆盖右侧继承类中的同名函数。为了说明方便,将这些混入类(Mixin)成为"工具类"。 django

源码组织

全部的视图相关代码,均存放与django/views/generic目录中: app

  • base.py 保存视图的抽象类,TemplateView和RedirectView,及工具类TemplateResponseMixin的代码 函数

  • create_update.py 基于函数的通用视图。已标记为deprecated 工具

  • date_based.py 基于函数的日期相关通用视图。已标记为deprecated 源码分析

  • dates.py 新的基于类的日期相关通用视图。用于取代date_based.py post

  • detail.py 基于类的单个对象显示相关的视图和工具类 url

  • edit.py 基于类的对象编辑相关的视图和工具类 spa

  • list.py 基于类的对象列表显示相关视图和工具类

  • list_detail.py 基于函数的列表、显示函数。已标记为deprecated

  • simply.py 基于函数的工具经常使用工具试图。已标记为deprecated

从逻辑上来看,源代码被组织为抽象基类,工具类(Mixin),常规(具体)实现和基于模型的实现。

源码分析

抽象类和经常使用视图(base.py)

这个文件包含视图的顶级抽象类(View),基于模板的工具类(TemplateResponseMixin),模板视图(TemplateView)和重定向视图(RedirectView)。

View及View的执行顺序

View是全部基于类的视图的基类。仅实现了一些基本的方法和必要的检查工做。其中最重要的是dispatch方法。再次方法中,根据HTTP请求中的method参数,调用相应的同名处理函数。这里留下了一个口子,后续的类须要根据本身的状况来填补这个口子最终完成一个视图的处理。

  • 属性

  • httpmethodnames 定义全部的Http metho['get','post','put','delete','head','options','trace']。

  • 方法

  • init 初始化方法

由URLConf调用。包含将关键字参数存入实例属性等功能。

若是一个视图包含一个实例属性,且在urlpattern中设置了相应的值。将配置的值赋给视图对象的方法就是由URLConf调用init函数时做为参数传入。View.init负责具体的赋值工做。

  1. as_view 类方法(classonlymethod)。返回Function-based视图函数对象。返回的视图函数对象("在被调用时")负责实例化视图,调用视图的dispatch方法。

  2. dispatch 调度函数。根据Http method调用视图的同名函数

  3. httpmethodnot_allowed 返回不被容许的http method处理函数

TemplateResponseMixin

提供使用模版渲染的工具类。template_name参数用于指定模版。但愿具有模版功能的视图能够直接继承此工具累计可。不过咱们不多直接在本身的视图中继承此工具类,由于Django已经提供了一组有用的视图来减小咱们的工做。

TemplateView

基于模版的视图 。须要提供附加数据,能够在继承此视图的子类中,重写getcontextdata方法。经常使用于诸如"about","copyrights" ,"terms"等基于文本的静态内容。只需设置template_name便可。甚至直接能够在URLConf中直接指定此参数。

如:


1 url(r'^about/$',TemplateView.as_view(template_name='about.html'))

RedirectView

重定向视图。能够说这个视图提供了彻底的重定向功能。不管是http get、post、delete仍是head、options都将重定向到url参数指定的地址。

permanent 属性指定是否返回永久(HTTP 301)重定向信息,不然返回临时重定向(HTTP 302),默认是true.

列表类通用视图(list.py)

此文件包含用于显示数据列表经常使用的类和工具类。不只能够方便的用于显示基于模型(Model)的数据列表,也能够用于显示自定义数据列表。

此图中绿色部分属于base.py,引入此图中是为了说明他们之间的关系

MultipleObjectMixin

最主要的核心工具类,主要的算法和接口所有都在这个工具类中实现。

  • 属性

allow_empty 默认值True。表示没有数据时显示空列表;不然将会产生一个404错误。

queryset 产生数据的queryset实例或"类queryset"数据列表。

model 关联的模型类。

paginated_by 分页的每页数据项数。默认不起用分页。

contextobjectname 保存到context中的对象名称。默认是$(model)_list。

paginator_class 默认值Paginator。分页处理器。

  • 方法

get_queryset 获取用于数据显示的列表对象。能够是类queryset对象。此方法优先选择使用queryset属性。未提供queryset属性时,返回model的默认管理器。若是也没有提供model属性,将会产生ImproperlyConfigured异常。

paginatequeryset 根据须要,将queryset分页。返回(paginator, page, page.objectlist, page.hasotherpages())

getpaginateby 返回每页数据项数。None表示不分页。

get_paginator 返回分页器

getallowempty 参见allow_empty属性说明

getcontextobjectname 参见contextobject_name属性说明

getcontextdata 设置视图的附加属性。一般重写此方法来为视图提供附加数据。 默认设计的视图数据:

'paginator': 分页器, 'page_obj': 页对象, 'is_paginated': 是否进行了分页, 'object_list': 视图的数据

*BaseListView*

视图列表基类。继承自MutipleObjectMixin和View。这是一个抽象类。此函数经过增长get方法来整合View的处理流程和MutipleObjectMixin提供的工具函数。

MultipleObjectTemplateResponseMixin

继承自TemplateResponseMixin,并重写gettemplatenames方法。追加$(applabel)/$(model)list.html做为默认模板。

ListView

本模块功能集大成者。通常都是直接继承此类,并重写MutipleObjectMixin的一些默认属性和/或方法来实现需求。

此类继承自MultipleObjectTemplateResponseMixin和BaseListView。通常来讲,只需提供model属性,并编写$(model)list.html便可实现数据列表功能。如需分页能够重写paginatedby属性,指定每页数据项数目。

相关文章
相关标签/搜索