21 django之FBV与CBV

一、FBV与CBV
1.FBV 基于函数的视图
def index(request):
        return HttpResponse(...)

2.CBV 基于类的视图——CBV会自动判断当前请求方法并自动匹配类中的方法执行

# 视图函数即可以是函数也可以是类
    from django.views import View
    class MyLogin(View):
        def get(self, request):
            return HttpResponse('get请求')
        def post(self, request):
            return HttpResponse('post请求')


url(r
'^login/', views.MyLogin.as_view()) """CBV会自动判断当前请求方法并自动匹配类中的方法执行"""
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    #FBV
    url(r"^index/",views.index),
    #CBV
    url(r"^login/",views.MyLogin.as_view())

]

为何能够做到自动匹配并执行??

二、CBV源码剖析——反射:通过字符串来操作对象的属性或者方法

函数名或者方法名遇到括号执行优先级最高

对象查找属性或方法的顺序
    永远都是先从自己身上找
    然后去产生对象的类中找
    再去类的父类中找 如果都没有才会报错

闭包函数
    定义在函数内部并且使用了外层函数名称空间中的名字

回去记得复习面向对象反射

FBV与CBV在路由匹配上本质其实是一样的
都是正则表达式对应函数名

 

 

 

 

 

 

温故知新:getattr通过字符串的形式获取对象的属性或方法

 

 口头表述CBV底层逻辑

 1. url(r"^login/",views.MyLogin.as_view())
as_view())里定义了一个view函数
2.view里面调用了一个self.dispatch
3.利用反射获取当前的方法,去类里面找有没有跟方法相同的方法名
4.找到了执行


# 突破口在urls.py
url(r'^login/',views.MyLogin.as_view())
# url(r'^login/',views.view)  FBV一模一样
# CBV与FBV在路由匹配上本质是一样的 都是路由 对应 函数内存地址
"""
函数名/方法名 加括号执行优先级最高
猜测
    as_view()
        要么是被@staicmethod修饰的静态方法
        要么是被@classmethod修饰的类方法  正确
        
    @classonlymethod
    def as_view(cls, **initkwargs):
        pass
"""

    @classonlymethod
    def as_view(cls, **initkwargs):
        """
        cls就是我们自己写的类   MyCBV
        Main entry point for a request-response process.
        """
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)  # cls是我们自己写的类
            # self = MyLogin(**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方法
        """

 

FBV与CBV在路由匹配上本质其实是一样的
    都是正则表达式对应函数名
    url(r'^login/', views.MyLogin.as_view())
    def as_view(cls, **initkwargs):
         def view(request, *args, **kwargs):
            # cls使我们自定义的类  MyLogin
            self = cls(**initkwargs)  # 产生一个MyLogin类的对象  obj 
            return self.dispatch(request, *args, **kwargs)
         return view
    
    def dispatch(self, request, *args, **kwargs):
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

 

 
posted @ 2021-11-25 21:30  甜甜de微笑  阅读(64)  评论(0编辑  收藏  举报