Django(CBV,FBV)
一.CBV
CBV(class base views)模式:url------类
Django的url是将一个请求分配给可调用的函数的,而不是一个class。针对这个问题,class-based view提供了一个as_view()静态方法,调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()方法进行分发,将get请求分发给cbv.get方法处理,将post请求分发给cbv.post方法处理
1.CBV优点
1.提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
2.可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
2.CBV实现过程:
浏览器通过url先执行Login类中的dispatch函数(分发器),dispatch会调用get/post方法
---------urls.py path('xxx',views.Login.as_view()) ---------views.py from django import views class Login(views.View): #继承于views.View类 def dispatch(self, request, *args, **kwargs): #这个函数(了解作用即可,可不写)作用类似于装饰器,源码中使用了反射
ret=super(Login,self).dispatch(request,*args,**kwargs) #重写dispatch方法(关键看传来的是那种请求方式,如果是get请求方式,就执行get方法) print(11111) return ret def get(self,request,*args,**kwargs): #函数名只能是get,一旦有get请求发来,就执行此函数 print("gettttttttt") return render(request,"login.html") def post(self,req,*args,**kwargs): #函数名只能是post,一旦有post请求发来,就执行此函数 user=req.POST.get("username") pwd=req.POST.get("password") rep=redirect("/index")return rep
3.CBV的无名、有名分组
url无名分组
from app01.views import LoginView urlpatterns = [ url(r'^admin/', admin.site.urls), # url(r'^login/',LoginView.as_view()), url(r'^login/(\d{2})',LoginView.as_view()) ]
from django.shortcuts import render,HttpResponse from django.views import View class LoginView(View): def get(self,req,nn): #因为urls中是无名分组,此时写任何参数都可以 print(nn) return render(req,"login.html") def post(self,req): print("post test") return HttpResponse("OK")
url有名分组
from django.conf.urls import url from django.contrib import admin from app01.views import LoginView urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/(?P<nn>\d{2})',LoginView.as_view()) ]
from django.shortcuts import render,HttpResponse from django.views import View # Create your views here. class LoginView(View): def get(self,req,nn): #因为urls中分组名称为nn,这里必须写成nn print(nn) return render(req,"login.html") def post(self,req): print("post test") return HttpResponse("OK")
4.CBV传参
from django.conf.urls import url from django.contrib import admin from app01.views import LoginView urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/(?P<nn>\d{2})',LoginView.as_view(name="xx")) #传参name="xx",要保证视图views.py中的LoginView类中有此属性(类属性) ]
from django.shortcuts import render,HttpResponse from django.utils.decorators import method_decorator from django.views import View # Create your views here. class LoginView(View): name="FFF" def get(self,req,nn): print(self.name) #此处打印"xx",name="FFF"被覆盖了 print(nn) lst = [1,2,"","",5] return render(req,"login.html",{"lst":lst}) def post(self,req): print("post test") return HttpResponse("OK")
二.视图加装饰器
在Django中,想要给CBV模式中类中的方法添加装饰器,有三种方法:
1.在类之上添加,使用name值
from django.shortcuts import render,HttpResponse from django.utils.decorators import method_decorator from django.views import View def wrapper(fun): def inner(*args,**kwargs): print("请求来了...") ret = fun(*args,**kwargs) print("请求退出...") return ret return inner #LoginView类中的get方法添加装饰器,语法糖只能一个个添加,如果想要给dispatch添加装饰器,要再加语法糖,将name="dispatch" @method_decorator(wrapper,name='get') class LoginView(View): def dispatch(self, request, *args, **kwargs): print("dispatch begin") ret = super().dispatch(request,*args,**kwargs) print("dispatch end") return ret def get(self,req,nn): print(self.name) print(nn) lst = [1,2,"","",5] return render(req,"login.html",{"lst":lst}) def post(self,req): print("post test") return HttpResponse("OK")
2.在dispatch方法上添加
from django.shortcuts import render,HttpResponse from django.utils.decorators import method_decorator from django.views import View def wrapper(fun): def inner(*args,**kwargs): print("请求来了...") ret = fun(*args,**kwargs) print("请求退出...") return ret return inner class LoginView(View): @method_decorator(wrapper) #给dispatch方法添加装饰器,就相当于给get、post方法都加上了 def dispatch(self, request, *args, **kwargs): print("dispatch begin") ret = super().dispatch(request,*args,**kwargs) print("dispatch end") return ret def get(self,req,nn): print(self.name) print(nn) lst = [1,2,"","",5] return render(req,"login.html",{"lst":lst}) def post(self,req): print("post test") return HttpResponse("OK")
3.在指定方法上添加
from django.shortcuts import render,HttpResponse from django.utils.decorators import method_decorator from django.views import View def wrapper(fun): def inner(*args,**kwargs): print("请求来了...") ret = fun(*args,**kwargs) print("请求退出...") return ret return inner class LoginView(View): def dispatch(self, request, *args, **kwargs): print("dispatch begin") ret = super().dispatch(request,*args,**kwargs) print("dispatch end") return ret @method_decorator(wrapper) #在get方法上添加装饰器,一旦有get请求传来就触发 def get(self,req,nn): print(self.name) print(nn) lst = [1,2,"","",5] return render(req,"login.html",{"lst":lst}) def post(self,req): print("post test") return HttpResponse("OK")