【Django面试】之深入CBV以及请求过程源码分析

CBV的介绍以及写法

CBV即为class base view,我们先写一个类,然后再类里面根据自己的需求写post,get,put等方法,类似这样
view里面这样写

class Home(View):

    def get(self, request):
        print('get() is called')
        return render(request, 'login.html')
    
    def post(self, request):
        print('post() is call')
        return render(request, 'login.html')

url里面这样写,注意as_view()是固定写法
在这里插入图片描述

源码分析

当请求过来的时候,执行这个类的as_view()方法,执行这个as_view()会怎样呢,如果你发来的是get请求就会执行get方法,如果你发来的是这个post请求,就执行post,CBV里边可以执行的方法有这么多个
在这里插入图片描述
使用类视图的时候,请求过来到底发生了什么过程呢,看下图请听我慢慢分析哈。
在这里插入图片描述
请求里面包含请求头和请求行,当一个请求过来的时候,Django先拿他的URL进行匹配,然后拿请求的Request Method,拿到Request Method之后,先通过dispatch()函数进行反射,从而执行类里边对应的方法,如果请求中是GET就执行类里边的get()方法。先看看dispatch的源码。
在这里插入图片描述
可见是通过反射实现的。这个dispatch相当于帮我们做了一个反射的功能,我们可以改造这个方法
在这里插入图片描述
实验发现,这样子那么get()和post()都没法执行了。所以它是先执行dispatch方法,然后通过反射去执行其他类里面的方法的。所以我们可以先继承父类的dispatch方法,在对他进行改造,实现自定义
在这里插入图片描述
这样子和不写dispatch没有区别。
在这里插入图片描述
这样写就相当于自定义了。

最后吃一份as_view的源码

@classonlymethod
    def as_view(cls, **initkwargs):
        """Main entry point for a request-response process."""
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don't do that."
                                % (key, cls.__name__))
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r. as_view "
                                "only accepts arguments that are already "
                                "attributes of the class." % (cls.__name__, key))
原创文章 85 获赞 120 访问量 4万+

猜你喜欢

转载自blog.csdn.net/happygjcd/article/details/104295163