Contents
  1. 1. 1.CBVs的使用原则
  2. 2. 2.如何使用mixin
  3. 3. 3.减少重复砌砖头?来看看通用视图
    1. 3.1. base.py
    2. 3.2. detail.py
    3. 3.3. list.py
    4. 3.4. edit.py
    5. 3.5. dates.py
  4. 4. 假装参考

原标题: 这两天摸鱼所得

将狗里cbv与fbv的优劣不阐述, cbv的多态继承与python这种oo语言风格上就保持了一致, 无论是呈现逻辑(View)与业务逻辑(Mixin)都能很好的进行拼接, 更别说有大量的第三方扩展了

1.CBVs的使用原则

代码越少越好

永远不要重复代码

View应当只包含呈现逻辑, 不应包括业务逻辑

保持view逻辑清晰简单

不要将CBVs用作403, 404, 500的错误处理程序

保持mixin简单明了

2.如何使用mixin

在编程中mixin是指为继承它的class提供额外的功能, 但它自身却不能单独使用的类. 在具有多继承能力的编程语言中, mixin可以为类增加额外功能或方法. 在Django中, 我们可以使用mixin为CBVs提供更多的扩展性, 当然在类继承过程中, 我们推荐以下原则:

Django自身提供的View永远在最右边

mixin依次在以上view的左边

mixin永远继承自Python的object类型

3.减少重复砌砖头?来看看通用视图

为了深入了解Django的通用view, 到了痛苦地读源码(文末附)的时候了. 当然如果你不写Django也不妨看看, 读一读或许对模板系统的理解有所启发

来来来我们进入Django.views.generic (anyway), 从简到繁

base.py

颜料盒base.py

class Super Docs
ContextMixin object A default context mixin that passes the keyword arguments received by get_context_data as the template context.
View object Intentionally simple parent class for all views. Only implements dispatch-by-method and simple sanity checking.
TemplateResponseMixin object A mixin that can be used to render a template.
TemplateView ContextMixin, TemplateResponseMixin, View A view that renders a template. This view will also pass into the context any keyword arguments passed by the URLconf.
RedirectView View A view that provides a redirect on any GET request.

三个继承Object的初始class, 这就好比绘图使用的三原色, 后面大部分的Mixin和View都是由它们变化而来. 其中:

ContextMixin包含一个get_context_data方法, 用于渲染模板数据

View是通用View,包含一个as_view的req到res响应方法, 提供http方法及其允许列表, 进行一些简单的检查

TemplateResponseMixin是用于渲染模板的方法, 包括指定模板路径和渲染引擎

这个TemplateView是个简单的模板View, 继承与上面三个对象, 定义了render_to_response, 相当于静态页面 (从fbv转过来的童鞋用这个View并且重写get_context_data方法就能完成简单的fbv->cbv的转换了)

RedirectView重定向View, 重写了get, 只需要处理GET请求的view, 使用url参数指定重定向页面

detail.py

detail.py里定义了一系列对象信息展示的view, 核心View是最后的DetailView

class Super Docs
SingleObjectMixin ContextMixin Provides the ability to retrieve a single object for further manipulation.
BaseDetailView SingleObjectMixin, View A base view for displaying a single object
SingleObjectTemplateResponseMixin TemplateResponseMixin -
DetailView SingleObjectTemplateResponseMixin, BaseDetailView Render a “detail” view of an object. By default this is a model instance looked up from self.queryset, but the view will support display of any object by overriding self.get_object().

SingleObjectMixin扩展了ContextMixin, 使其能够使用model,query等获取对象, 然后通过设置定义的context_object_name去渲染模板内定义的字段

BaseDetailViewview上使用了SingleObjectMixin, 给get方法添加了将对象转化为context(上下文)的操作, 使其成为一个能够请求处理对象的基础view, 但是还没有渲染方法, 不设置的原因是还能够绑定删除mixin成为BaseDeleteView

SingleObjectTemplateResponseMixin无说明, 但是从代码上看是除了渲染方法以外,额外定义默认对象渲染模板名称 默认页面后缀_detail 这个方法多次复用于base类view, 给基础对象处理类view提供渲染方法

DetailView详情View, 单纯地继承BaseDetailViewSingleObjectTemplateResponseMixin

list.py

list.py用于展示列表, 写法与detail.py类似, 核心View是ListView

class Super Docs
MultipleObjectMixin Context A mixin for views manipulating multiple objects.
BaseListView MultipleObjectMixin, View A base view for displaying a list of objects.
MultipleObjectTemplateResponseMixin TemplateResponseMixin Mixin for responding with a template and list of objects.
ListView MultipleObjectTemplateResponseMixin, BaseListView Render some list of objects, set by self.model or self.queryset. self.queryset can actually be any iterable of items, not just a queryset.

MultipleObjectMixinSingleObjectMixin不同的方式扩展了ContextMixin, 使其能够使用model等获取queryset之外, 额外提供了页面分页功能及其参数和方法

BaseListView是一个能够请求处理对象列表的基础view, 但是还没有渲染方法

MultipleObjectTemplateResponseMixin功能都差不多..

ListView单纯继承上面两个

edit.py

edit.p涉及了CRUD, 所以引入了form的概念, 核心View为CreateView,UpdateView,DeleteView,这里的View比较耳熟吧

class Super Docs
FormMixinBase type -
FormMixin six.with_metaclass(FormMixinBase, ContextMixin) A mixin that provides a way to show and handle a form in a request.
ModelFormMixin FormMixin, SingleObjectMixin A mixin that provides a way to show and handle a modelform in a request.
ProcessFormView View A mixin that renders a form on GET and processes it on POST.
BaseFormView FormMixin, ProcessFormView A base view for displaying a form
FormView TemplateResponseMixin, BaseFormView A view for displaying a form, and rendering a template response.
BaseCreateView ModelFormMixin, ProcessFormView Base view for creating an new object instance. Using this base class requires subclassing to provide a response mixin.
CreateView SingleObjectTemplateResponseMixin, BaseCreateView View for creating a new object instance, with a response rendered by template.
BaseUpdateView ModelFormMixin, ProcessFormView Base view for updating an existing object. Using this base class requires subclassing to provide a response mixin.
UpdateView SingleObjectTemplateResponseMixin, BaseUpdateView View for updating an object, with a response rendered by template.
DeletionMixin object A mixin providing the ability to delete objects
BaseDeleteView DeletionMixin, BaseDetailView Base view for deleting an object. Using this base class requires subclassing to provide a response mixin.
DeleteView SingleObjectTemplateResponseMixin, BaseDeleteView View for deleting an object retrieved with self.get_object(), with a response rendered by template.

注: six是一个python2和python3兼容库.

FormMixinBase继承type定义了一个类型, 重写了__new__, 内容暂时看不懂:)

FormMixin表单逻辑, 这里就定义了几个重要的属性和方法, 用户使用formform_class, 成功回调urlsuccess_url 表单合法form_valid 表单不合法form_invalid

ModelFormMixin进一步扩展FormMixin, 提供fields字段使用户能够处理ModelForm, form_valid中添加了保存操作

ProcessFormView功能View, 重写了View的get和post方法(put直接return post方法) 使View能够在get的时候 渲染form内容, post的时候能提交form内容

BaseFormView 相当于给ProcessFormView提供了表单处理逻辑, 相当于能处理一些简单的请求了

FormView 继续给BaseFormView加上模板渲染引擎, 处理结果能从前台渲染出来了

BaseCreateViewBaseFormView类似, 不过其使用的是modelForm, form_valid会调用form.save()方法, getpost中执行了一句self.object = None 其作用于SingleObjectMixinget_context_data方法中 (detail.py 103-107行,判断self.object不为空时执行取址操作 v1.9.5)

CreateView 单纯基础BaseCreateViewSingleObjectTemplateResponseMixin,别忘了后者只是是一个轻度继承的渲染工具 默认页面后缀_form

BaseUpdateViewBaseCreateView代码几乎相同, 除了self.object = None改为self.object = self.get_object() 作用于相同位置, 进行字典更新操作

UpdateView 单纯基础BaseUpdateViewSingleObjectTemplateResponseMixin 默认页面后缀_form

DeletionMixin 新的颜料,因为功能使用不频繁所以单独放在这里, 提供了delete方法和success_url属性, delete执行self.object.delete()后会自动执行页面回调. 特别注意的是, 这里只有post方法return了delete方法, 其他方法暂不支持

BaseDeleteViewBaseDetailView绑定删除功能, 仅简单继承, 无页面渲染 简单的删除后跳转

DeleteView 单纯继承BaseDeleteViewSingleObjectTemplateResponseMixin, 默认页面后缀_confirm_delete, 给一个删除页面, get即渲染一个页面, 给个表格, post到这个页面后将删除对象

dates.py

这是一个基于时间的页面通用view模板, 但是除了博客之类的基本上用不着, 不阐述.

假装参考

weiguda的博客

(这篇博文原意是好的, 但是读着感觉变成django-braces文档了, 那我为啥不去看源文档呢呢)

django官方文档

这些通用view的具体简单实例.

django.views.generic源码

本文源码 顺带一提 Django中admin还是保持fbv风格(逃

Contents
  1. 1. 1.CBVs的使用原则
  2. 2. 2.如何使用mixin
  3. 3. 3.减少重复砌砖头?来看看通用视图
    1. 3.1. base.py
    2. 3.2. detail.py
    3. 3.3. list.py
    4. 3.4. edit.py
    5. 3.5. dates.py
  4. 4. 假装参考