Django进阶之FBV和CBV
Django请求生命周期
Django的请求生命周期是指当用户在浏览器上输入url到用户看到网页的这个时间段内,Django后台所发生的事情。
- 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端。
- url经过Django中的wsgi,再经过Django的中间件,最后到达路由映射表,在路由中一条一条进行匹配,一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了。
- 视图函数根据客户端的请求查询相应的数据,返回给Django,然后Django把客户端想要的数据做为一个字符串返回。
- 经过一系列的中间件,最后到达客户端。
- 客户端浏览器接收到返回的数据,经过渲染后显示给用户。
上面是FBV模式的请求过程。其实除了FBV之外Django还支持CBV模式。CBV模式的请求过程和FBV有些不同(下面会讲解二者的不同)。
当服务端使用CBV模式的时候,服务端通过路由映射匹配成功后会自动去执行对应类中的dispatch方法,然后会通过dispatch反射
的方式找到类中对应的方法并执行类中的方法,执行完毕之后,会把客户端想要的数据返回给dispatch方法,由dispatch方法把数据返回给客户端。
FVB
FBV(function base views)基于函数的视图, 就是在视图里使用函数处理请求。
urls.py:
urlpatterns = [
url(r'^index/', views.index),
]
views.py:
def index(request):
if request.method == 'GET':
return HttpResponse('GET请求')
elif request.method == 'POST':
return HttpResponse('POST请求')
FBV模式需要自己判断请求方式,根据请求方式的不同执行不同的操作。
CBV
CBV(class base views)基于类的视图, 就是在视图里使用类处理请求。
urls.py:
urlpatterns = [
url(r'^student/', views.StudentView.as_view()),
]
views.py:
from django.views import View
class StudentView(View):
def get(self, request, *args, **kwargs):
return HttpResponse('GET请求')
def post(self, request, *args, **kwargs):
return HttpResponse('POST')
当服务端使用CBV模式的时候,服务端通过路由映射匹配成功后会自动去执行对应类中的dispatch方法,然后会通过dispatch反射的方式找到类中对应的方法并执行类中的方法,执行完毕之后,会把客户端想要的数据返回给dispatch方法,由dispatch方法把数据返回给客户端。
帮助理解CBV的执行过程:
class StudentView(View):
# 调用父类的dispatch(默认),并做些自己需要的操作
def dispatch(self, request, *args, **kwargs):
if request.method == 'GET': # 在指定的请求方法到来时先做的操作。
print('GET 请求')
print('before') # 在所有的请求方法到来时先做的操作
result = super(StudentView, self).dispatch(request, *args, **kwargs)
print('after')
return result
# 拦截(证明最后的数据是由dispatch返回给客户端的)
# def dispatch(self, request, *args, **kwargs):
# return HttpResponse('拦截')
# 自定义dispatch
# def dispatch(self, request, *args, **kwargs):
# func = getattr(self, request.method.lower()) # self = StudentView()
# return func(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return HttpResponse('GET请求')
def post(self, request, *args, **kwargs):
return HttpResponse('POST')
当有多个视图类都需要在dispatch方法中执行一些形同的操作是我们可以采用继承的方式:
class MyBaseView(object): def dispatch(self, request, *args, **kwargs): if request.method == 'GET': # 在指定的请求方法到来时先做的操作。 print('GET 请求') print('before') # 在所有的请求方法到来时先做的操作 result = super(MyBaseView, self).dispatch(request, *args, **kwargs) print('after') return result class StudentView(MyBaseView, View): def get(self, request, *args, **kwargs): return HttpResponse('GET请求') def post(self, request, *args, **kwargs): return HttpResponse('POST') class TeacherView(MyBaseView, View): def get(self, request, *args, **kwargs): return HttpResponse('TeacherView中的GET请求') def post(self, request, *args, **kwargs): return HttpResponse('TeacherView中的POST请求')
在上面的代码中我们需要弄明白的一点是super()的作用,看下面这行代码
result = super().dispatch(request, *args, **kwargs)
我们平常可能认为上面这行代码的super()是执行MyBaseView类的父类中的dispatch方法,但是我们会发现MyBaseView的父类继承的是object类,但是object类中没有dispatch方法啊,这是怎么回事呢。
其实super()并不是简单的执行父类中的方法。super(MyBaseView, self) 获得的是 MyBaseView类 在 self这个对象的 MRO 列表中的下一个类。关于super()的详细介绍转到你不知道的super

浙公网安备 33010602011771号