摘要
本文部分内容来源于网络,个人收集整理,请勿传播
Django框架中View知识点
- FBV和CBV
- View
1 | 'View', 'TemplateView', 'RedirectView', 'ArchiveIndexView', |
FBV和CBV
Django中有以下两种视图使用方式
FBV(function base view)
函数视图CBV(class base view)
类视图
FBV
函数视图比较容易理解,相当于将对应的路由请求分发到指定函数。
路由配置
1 | urlpatterns = [ |
视图函数
1 | from django.shortcuts import render |
CBV
用类其实是为了抽象,抽象出通用的,将可变的暴露出来,这样我们就可以用最少的代码实现复杂的功能了
类视图在配置路由时需要使用as_view
方法。
路由配置
1 | urlpatterns = [ |
视图类
1 | from django.views import View |
CBV原理解析
as_view
方法是继承的View类中定义的
1 |
|
其实在as_view
方法中定义了一个view函数,这个函数接受的参数跟FBV中的函数接受的参数一样,但是这个函数并不处理对应的http请求,而是把这项工作交给了dispatch方法去完成,最后as_view方法返回了这个view函数(闭包)。
1 | def dispatch(self, request, *args, **kwargs): |
在dispatch方法中,dispatch通过反射的方式找到类中对应的方法(如:get、post等),执行对应的业务逻辑并返回执行结果
CBV常用的view
Django中,对那些我们平时经常用的View进行了封装,比如用于渲染一个template的TemplateView,用于处理重定向的RedirectView,用于处理表单的FormView,用于处理数据库对象的DetailView和ListView等,这些View有一个共同的父类:View
TemplateView
TemplateView继承了三个类
- TemplateResponseMixin:提供
render_to_response
等方法 - ContextMixin:提供
get_context_data
方法 - View: 提供
as_view
、dispatch
等方法
所以as_view()
方法之后调用dispatch
方法的过程不变,接下来是对应的http方法略有不同
1 | class TemplateView(TemplateResponseMixin, ContextMixin, View): |
dispatch
方法调用get
方法,先执行get_context_data
方法
1 | class ContextMixin: |
ContextMixin类则只是实现了一个方法,get_context_data()
,这是为在渲染template
的时候,提供了一个默认的context,一般子类都会重写这个方法的。
得到context
之后,传给render_to_response
方法去构造TemplateResponse对象,渲染模板,返回。
1 | class TemplateResponseMixin: |
使用
1 | # 指定页面 |
ListView
ListView
继承了以下几个类
- BaseListView:提供
get
方法- View:提供
as_view
、dispatch
等方法 - MultipleObjectMixin:提供
get_queryset
、get_context_data
等相关方法- ContextMixin:提供
get_context_data
方法
- ContextMixin:提供
- View:提供
- MultipleObjectTemplateResponseMixin:提供
get_template_names
方法- TemplateResponseMixin:提供
render_to_response
等方法
- TemplateResponseMixin:提供
1 | class ListView(MultipleObjectTemplateResponseMixin, BaseListView): |
入口依旧是as_view()
方法之后调用dispatch
方法的过程不变,接下来是对应的http方法
1 | class BaseListView(MultipleObjectMixin, View): |
get
方法中先调用get_queryset
获取model中的数据,然后调用get_context_data
方法将数据封装到context中
1 |
|
得到context
之后,传给render_to_response
方法去构造TemplateResponse对象,渲染模板,返回。
MultipleObjectTemplateResponseMixin
类中重新定义了render_to_response
方法调用的get_template_names
方法,添加了一个模板${app_name}/${model_name}_list.html
1 | class MultipleObjectTemplateResponseMixin(TemplateResponseMixin): |
使用
1 | # 指定了数据表。他的功能相当于取出了Article中的所有数据 |
DetailView
DetailView
继承了以下几个类
- BaseDetailView:提供
get
方法- View:提供
as_view
、dispatch
等方法 - SingleObjectMixin:提供
get_queryset
、get_context_data
等相关方法- ContextMixin:提供
get_context_data
方法
- ContextMixin:提供
- View:提供
- SingleObjectTemplateResponseMixin:提供
get_template_names
方法- TemplateResponseMixin:提供
render_to_response
等方法
- TemplateResponseMixin:提供
1 | class DetailView(SingleObjectTemplateResponseMixin, BaseDetailView): |
入口依旧是as_view()
方法之后调用dispatch
方法的过程不变,接下来是对应的http方法
1 | class BaseDetailView(SingleObjectMixin, View): |
get
方法中先调用get_object
获取model中的数据,然后调用get_context_data
方法将数据封装到context中
1 | class SingleObjectMixin(ContextMixin): |
得到context
之后,传给render_to_response
方法去构造TemplateResponse对象,渲染模板,返回。
SingleObjectTemplateResponseMixin
类中重新定义了render_to_response
方法调用的get_template_names
方法,添加了一个模板${app_name}/${model_name}_detail.html
1 | class SingleObjectTemplateResponseMixin(TemplateResponseMixin): |
使用
1 | url(r'^persons/(?P<pk>\d+)/$', PersonDetailView.as_view(), name='detail'), |