CBV

一.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())
]
urls.py
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")
views.py

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())
]
urls.py
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")
views.py

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类中有此属性(类属性)
]
urls.py
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")
views.py

二.视图加装饰器

在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")
@method_decorator(wrapper,name='get')

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")
给dispatch方法添加装饰器,就相当于给get、post方法都加上了

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")
在get或post上添加
原文地址:https://www.cnblogs.com/ly0123/p/11938594.html