一.请求生命周期
请求生命周期指用户的1次访问,在Server后台发生的全部事项
1.Client发送HTTP请求
-以get方式提交,请求体中无内容,数据在请求头中
-以post方式提交,请求体和请求体中都可以放数据
-其他方式包括put,patch,delete,head,options,trace
2.Server接收后解析URL,到达URLconf
请求头数据(str)-->request.GET
请求体数据,即request.body(str)-->request.POST(dict)
3.在urlpatterns中由上到下依次匹配
4.匹配成功后,进入对应的View Function/View Class
-FBV:URL-->View Function
-CBV:URL-->View Class
5.在View中进行业务处理
-根据需求定制
-操作数据库
--支持原生SQL
--Django ORM
-响应内容:返回结果
-响应头
-响应体
二.FBV和CBV
1.FBV(Function Base Views):
就是指在视图里使用函数处理请求
参见 视图函数 部分
2.CBV(Class Base Views)
就是指在视图里使用类处理请求
在Django1.3之前,Generic View(通用视图)使用的是FBV,但Python的1个重要特性就是面向对象
如果只用函数进行开发,很多面向对象的优点就错失了(继承,封装,多态),所以后来加入了CBV
Class比Function更能利用多态的特性,因此更容易从宏观层面上将项目中通用的功能抽象出来
CBV的实现大体就是请求由URLconf到类后,通过类内部的dispatch()进行分发
dispatch()定义在自定义类继承的View类中,基本原理为利用反射
func_name=getattr(对象,请求类型),然后func_name()执行相应方法
将GET请求分发给<class>.get()处理,将POST请求分发给<class>.POST()处理,其他请求类型类似
将执行结果再返回给dispatch(),dispatch()再将结果(经多步后)返回给用户
优点:
1.提高了代码的复用性,可以使用面向对象的技术,如Mixin(多继承)
2.可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
(1)使用CBV
#views.py中:
from django.http import HttpResponse
from django.views import View
class MyView(View):#必须继承View类
#def dispatch(self,request,*args,**kwargs):#自行定义dispatch()
#ret=super(MyView,self).dispatch(request,*args,**kwargs)
#调用父类的dispatch()并接收结果
#get()和post()的共同功能可以放在这里
#return ret
def get(self,request):#用于GET请求
return HttpResponse("GET")
def post(self,request):#用于POST请求
return HttpResponse("POST")
Django的urlpatterns将请求分配给可调用的函数,而不是分配给类
针对这个问题,CBV提供了as_view()静态方法(也就是类方法),该方法会创建1个类的实例
然后通过实例调用dispatch(),根据request.method调用相应方法处理请求(如get()/post())
CBV也是接收request,返回response;如果方法没有定义,抛出HttpResponseNotAllowed异常
#urls.py
from django.conf.urls import url
from myapp.views import MyView
urlpatterns=[
url(r'^index/$',MyView.as_view()),
#指向1个类;.as_view()是固定写法
#找到类后再根据request.method找到对应方法(get()或post())
]
(2)CBV中2种设置类属性的方法:
1.常见的Python的方法:
from django.http import HttpResponse
from django.views import View
class GreetingView(View):
name="yuan"
def get(self, request):
return HttpResponse(self.name)
#可以被子类覆盖:
class MorningGreetingView(GreetingView):
name="alex"
2.在url中指定类的属性:
urlpatterns=[
url(r'^index/$', GreetingView.as_view(name="egon")),
]
(3)使用Mixin:
为了利用多态,CBV里引入了Mixin:就是写好一些基础类,然后通过不同Mixin的组合得到想要的类
Django中使用Mixin来重用代码,1个View Class可以继承多个Mixin,但只能继承1个View(包括View的子类)
推荐把View写在最右边,多个Mixin写在左边