Django视图层--FBV与CBV

Posted xiongsheng666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django视图层--FBV与CBV相关的知识,希望对你有一定的参考价值。

Django视图层–FBV与CBV

FBV与CBV

视图是可以用来调用的,用来处理请求(request)并返回响应(response)

Django的视图有两种形式 : FBV与CBV

FBV 是基于函数的视图 (function base views)

CBV 是基于类的视图(class base views)

视图函数可以是函数也可以是类

代码展示:

# urls.py
from django.contrib import admin
from django.urls import path

from environment import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('fbv/', views.test_fbv),
    path('cbv/', views.TestCBV.as_view())
]

# views.py
from django.shortcuts import render, HttpResponse

from django.views import View


def test_fbv(request):
    return render(request, "login.html")

"""只要是处理业务逻辑的视图函数 形参里面肯定要有request"""
class TestCBV(View):
    def get(self, request):
        return HttpResponse("CBV")

CBV源码剖析

# 突破口在urls.py
 path('cbv/', views.TestCBV.as_view())
#  path('cbv/', views.view)  FBV一模一样

注意不要修改源码 出了bug很难找

CBV与FBV在路由匹配上本质是一样的 都是路由 对应 函数内存地址

函数名/方法名 加括号执行优先级最高
猜测
    as_view()
        要么是被@staticmethod修饰的静态方法
        要么是被@classmethod修饰的类方法  正确
        
    @classonlymethod
    def as_view(cls, **initkwargs):
        pass

    @classonlymethod
    def as_view(cls, **initkwargs):
        """
        cls就是我们自己写的类   TestCBV
        Main entry point for a request-response process.
        """
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)  # cls是我们自己写的类
            # self = TestCBV(**initkwargs)  产生一个我们自己写的类的对象
            return self.dispatch(request, *args, **kwargs)
            """
            在看python源码的时候 一定要时刻提醒自己面向对象属性方法查找顺序
                先从对象自己找
                再去产生对象的类里面找
                之后再去父类找
                ...
            总结:看源码只要看到了self点一个东西 一定要问你自己当前这个self到底是谁
            """
        return view
CBV的精髓

def dispatch(self, request, *args, **kwargs):
    # 获取当前请求的小写格式 然后比对当前请求方式是否合法
    # get请求为例
    # post请求
    # 在这里做路由分发,把请求方式跟我们自己写的方法名字匹配做分发
    if request.method.lower() in self.http_method_names:
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)

        """
        反射:通过字符串来操作对象的属性或者方法
            handler = getattr(自己写的类产生的对象,'get',当找不到get属性或者方法的时候就会用第三个参数)
            handler = 我们自己写的类里面的get方法
        """
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)
    """
    自动调用get方法
    """

我们可以看出CBV在内部做了一个分发本质和FBV是一样的

CBV如何添加装饰器

from django.views import View
from django.utils.decorators import method_decorator
"""
CBV中django不建议你直接给类的方法加装饰器
无论该装饰器能都正常给你 都不建议直接加
"""

# @method_decorator(login_auth,name='get')  # 方式2(可以添加多个针对不同的方法加不同的装饰器)
# @method_decorator(login_auth,name='post')
class MyLogin(View):
    @method_decorator(login_auth)  # 方式3:它会直接作用于当前类里面的所有的方法
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request,*args,**kwargs)
    # @method_decorator(login_auth)  # 方式1:指名道姓
    def get(self,request):
        return HttpResponse("get请求")

    def post(self,request):
        return HttpResponse('post请求')

以上是关于Django视图层--FBV与CBV的主要内容,如果未能解决你的问题,请参考以下文章

Django框架之视图层(views)介绍

Django CBV源码分析

python(十九):django之FBV和CBV

Django视图函数之FBV与CBV模式

Django的View(视图)settings源码的解析模板层

Django——CBV与FBV