【武sir】django rest framework源码和实战_day01(上)

 (0)摘要

# 课程链接

4天搞定django rest framework源码和实战_哔哩哔哩_bilibili

# 课程内容

(1)内容概要_略

(2)内容回顾_略

(3)django 视图之 CBV 基本使用

(4)django 视图之 CBV 源码流程

(5)django 视图之面试题和 csrf 补充

(6)django 视图之 CBV 和解决 csrf 认证

(7)以上内容梳理_略

【知识点补充---自己加的】


# 岂曰无衣,与子同袍

(2)内容回顾_略

# (1)直接上图

【武sir】django rest framework源码和实战_day01(上)_第1张图片


# (2)Django 的 FBV 和 CBV

                1)FBV 就是基于函数的视图, 就跟我们平时使用的一样。

【武sir】django rest framework源码和实战_day01(上)_第2张图片

                2)CBV 是基于类的视图。就是要继承 django.views 中的 View 。见下图所示的代码。当执行了这一个类的时候,前端传来是什么请求,类就会自动执行相应的方法。比如 post 请求,那么类就会执行 post 的方法。

【武sir】django rest framework源码和实战_day01(上)_第3张图片

                此时路由函数要这么写,就是要加 .as_view() 来作为路由函数,这里是固定的要求,不为什么。 

【武sir】django rest framework源码和实战_day01(上)_第4张图片

                那么上面就是一个 CBV 的模式。


# (3)postman 伪造请求

                1)我们不可能为每一种请求再去设计相应的表单提交什么的,这没意义。我们可以使用 postman 这种工具来伪造各种请求,来查看后端返回的数据。

                

                2)postman 的下载安装。下载链接:Download Postman | Get Started for Free

// 下载完成后,我们直接打开后就会自动安装了,并且在桌面生成快捷方式。这个时候打开该快捷方式,即如下图所示。其实 postman 有网页端,但是需要桌面代理才能测试本地的 url 。 

【武sir】django rest framework源码和实战_day01(上)_第5张图片

                3)postman 简单使用。如下图所示,我们点了加号之后的页面,然后我们也具体的使用了下,测试了 post 请求。这里的报错是因为我们没有关闭 django 中的 csrf 认证。这里可以直接去 settings.py 文件中的中间件处注释掉该认证即可。

【武sir】django rest framework源码和实战_day01(上)_第6张图片


# (4)列表生成式,直接给我写的代码和注释吧

【武sir】django rest framework源码和实战_day01(上)_第7张图片


# (5)面向对象

                1)封装。体现在两个方面,一个方面是对同一类方法封装到类中。如下图所示,就是将各自类的对应自己方法,然后进行封装。 

【武sir】django rest framework源码和实战_day01(上)_第8张图片

               

                另外一个是将数据封装到对象中,就是我们将数据传入到类里面,然后里面的 self.a1 = 传参 a1,大致就是这个意思,供类的调用,也就是我们实例化这个类后,我们不仅能使用类的方法,还有里面的数据。

【武sir】django rest framework源码和实战_day01(上)_第9张图片

                2)简单聊聊装饰器 @property,这个装饰器的作用会在别的数据分析的课里面细讲,我们只需要知道,在定义函数的前面引用。之后我们在调用该函数的时候,就可以不加括号了,就跟调用属性一样。见下面的代码块,算是一种入门级别的理解吧。

# -*- coding=utf-8 -*- 
# github: night_walkiner
# csdn: 潘迪仔

class Foo:
    def __init__(self):
        self.price = 100

    # (1) 装饰器,这里必须写在最前面,函数名就是后续调用时候用的,
    # 而且 @property 装饰后的函数,必须是返回某个值,然后调用是属性调用,就是对方法不用加括号
    # 这里必须提一句,如果我们之后要赋值,比如下面的代码:
    """
    类 Foo 下的
    
    @property
    def price(self,value):
        pass
        
    之后调用的时候,如果我们 Foo.price 会提示少一个参数,
    而如果我们这样 Foo.price(100) ,依然会报错,
    因此我们要使用装饰器要求的设置,即下面的方式来设置数值什么的
    
    """

    @property
    def price(self):

        return print("装饰器")

    # 如果今后我们要对 price 进行赋值的话,必须装饰 price.setter ,
    # 注意观察啊!!!
    @price.setter
    def price(self, value):

        self.price = value

    # 这个是一样的,也是要用(1) 中定义的 price 来 .deleter 作为装饰器
    @price.deleter
    def price(self):
        del self.price

                那么来上一个实例看看,就是武 sir 写的代码,我就不复现了。这里是也是封装实例的扩展,很简单。如果遇到问题去复现一下,或者研读下吧,不赘述了。

【武sir】django rest framework源码和实战_day01(上)_第10张图片


(3)django 视图之 CBV 基本使用

# (1)内容详细

                1)关于 CBV 开发的结构。事实上 HTTP 请求本质上是发了一堆字符串,通过 /r 进行分隔的。但是我们是怎么处理请求的呢? Django 源码中是使用反射来做的,也就是 getattr() 方法来做。如果不使用反射方法,我们就要使用 request.method 去一个个做判断执行。(基本所有支持 CBV 结构的框架都是使用反射去实现的)

                2)对于 CBV 而言,我们使用了这种模式的时候,实际上就是在路由地址,执行了 as_view() 的方法,然后我们可以看 as_view() 的源码,可以看到不论是执行什么请求,都要执行 self.dispatch() 

【武sir】django rest framework源码和实战_day01(上)_第11张图片

                 

                3)self.dispatch 的源码如下,首先将获取的 request.method 的请求变小写,比如原来的是 GET 变成 get,然后判断这个请求是不是在  self.http_method_names 里面,这个self.http_method_names 里面存着的是各自请求类型,如 post,put 等等。 getattr(x, "y") 相当于 x.y 的意思,类似属性调用。

【武sir】django rest framework源码和实战_day01(上)_第12张图片

                4)CBV 的具体流程

                5)父类和子类的方法的执行顺序。见下图所示的代码:

【武sir】django rest framework源码和实战_day01(上)_第13张图片

                如下图所示,比如当前是 post 请求,然后我们执行了 dispatch 方法。

                第一: 那么系统就会从子类中找到 dispatch ,子类又会去父类里面找父类的 dispatch,但是 self 是代指子类,经过反射后找到的是 post 请求,

                第二: 然后再从子类中调用 post 方法,将结果再返回给父类的 dispatch, 父类的 dispatch 再传回给子类的 dispatch ,然后再返回给用户。

【武sir】django rest framework源码和实战_day01(上)_第14张图片


(4)django 视图之 CBV 源码流程(最好再多想想,这一块老师讲的不是很清晰)

# (1)CBV 源码流程的补充。相信这一块会随着深入学习而更扎实,且有更好的理解。

【武sir】django rest framework源码和实战_day01(上)_第15张图片


# (2) 继承


(5)django 视图之面试题和 csrf 补充

# (1)Django 中间件

                1)Django 中间件最多只能写 5 个方法,就是下图列举的。以前说的 process_request() 和 process_response() 两种方法是最常用的而已。

【武sir】django rest framework源码和实战_day01(上)_第16张图片

                其中 process_exception() 方法是只有异常的时候才会执行,没有异常就不会执行。对于 process_render_template() 方法,如果视图函数返回的是 render() 就会执行这个中间件,否则执行 HttpResponse() 的话是永远不会执行。

                

               

                2)中间件的执行流程 _(Django 1.10 以上的版本),见下图所示,我们简述一下中间件的执行流程,当请求进来的时候:

                第一:首先是按序执行所有中间件的 process_request() 方法,然后进行路由匹配,但是不执行视图函数;

                第二:执行完路由匹配后,再返回第一层中间件,继续按序执行他们的 process_view() 方法,执行完后才开始执行视图函数;

                第三:视图函数正确执行和返回(HttpResponse)的时候,就开始执行 process_response() 方法返回给浏览器。

                第四:如果说,在执行路由函数时候发生错误,那么就会执行 process_exception() 方法返回异常;

                第五:如果说,视图函数正确执行了,但是返回的是 render() 那么就执行中间件的process_render_template() 方法,然后返回给浏览器。

【第四、第五就是下图见注释的部分。】

【武sir】django rest framework源码和实战_day01(上)_第17张图片

                3)使用中间件能做什么?比较常用的就是权限认证和用户登录认证。


# (2)csrf 认证的面试题

                1)Django 中的中间件 csrf_token 的实现。csrf 的中间件是写在了 process_view() 方法里面的。【见后面的(3)的 3)的讲解】

【武sir】django rest framework源码和实战_day01(上)_第18张图片


# (3)免除 csrf 认证装饰器和单独 csrf 认证的装饰器

                1)假设我们将全局的视图函数都添加了 csrf 认证,也就是在中间件的地方给 csrf 打开认证了,那么我们如果想免除某个视图函数的 csrf 认证就可以使用免除认证的装饰器了。那么导入的模块语句为:from django.views.decorators.csrf import csrf_exempt

如下图所示,那么我们在视图函数 users 前引用了 @csrf_exempt 就是免除该函数的 csrf 认证了。 

【武sir】django rest framework源码和实战_day01(上)_第19张图片

                2)场景二,如果我们注释了全局的 csrf 认证,又想对某几个特定的视图函数加上 csrf 认证,那么就可以使用单独的 csrf 装饰器了。导入模块的语句为:from django.views.decorators.csrf import csrf_protect  。使用方法是和免除的装饰器一样的。如下图所示。

【武sir】django rest framework源码和实战_day01(上)_第20张图片

                3)有了上面的基础,我们就知道为什么 csrf 的认证需要写在 process_view() 中了,这是因为在执行认证的时候,需要检索这个视图函数是否免除了认证(或者带有认证),这里面是需要逻辑判断的。而如果写在 process_request() 方法中,请求过程并没有路由匹配的信息,csrf 都没找到视图函数,还谈什么检查视图函数是否带有相应的装饰器!紧接着,如果需要 csrf 认证,那么再去检查是否符合 csrf_token 的规则


(6)django 视图之 CBV 和解决 csrf 认证

# (1)CBV 怎么自定义 csrf 认证(自定义就是免除或是单独设置认证)

                1)前面我们讲的都是基于 FBV 的来讲解 csrf 装饰器的用法的。那么对于 CBV 要自定义 csrf 认证的话,就不是简单的在类中的函数上加装饰器了。【csrf 装饰器就是 csrf_exempt 或者 csrf_protect】

               

                2)解决方法就是使用  from django.utils.decorators import method_decorator 中的 method_decorator 装饰器,这可以对 CBV 结构设置自定义 csrf 装饰器用的。比如第一种方法就是如下的方法,@method_decorator(csrf_exempt) 那么就是免除这个视图类的 csrf 认证(对于单独设置也是一样的)。其实就是 @method_decorator(csrf 装饰器),只要是按照如下的格式就行。

class StudentsView(View):
    # 自定义认证---方法一, 就是放在 dispatch 方法前面。
    # 这是官方规定的,没有为什么。

    @method_decorator(csrf_exempt)      
    def dispatch(self, request, *args, **kwargs):
        print("before")
        # super() 不是简单的继承当前类的父类,而是执行整个继承关系
        # 也就是说,找方法的时候,先在自己里面找,找不到采取父类找,
        # 如果父类再找不到,就去第二继承类去找
        ret = super(StudentsView, self).dispatch(request, *args, **kwargs)
        # print(ret)
        print("after")

        return ret
    
    def get(self, request, *args, **kwargs):
        print("get")
        return HttpResponse("GET")
    
    # @method_decorator(csrf_exempt)   如果是加在这里是没用的!!!
    #(也就是对单独方法是无效的)
    # 因为官方规定了,就是要放在 dispatch 方法上面,而且 dispatch 还得放在最前面。
    def post(self, request, *args, **kwargs):

        return HttpResponse("POST")

    def put(self, request, *args, **kwargs):

        return HttpResponse("PUT")

    def delete(self, request, *args, **kwargs):

        return HttpResponse("DELETE")

               

                3)也可以是下面的方法,就是放在视图类的最上面,但是编写的时候就是@method_decorator(csrf 装饰器,name="dispatch")。具体见下面代码的注释。

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt, csrf_protect

# 自定义认证---方法二, name里面其实就是方法名。简单说就是找到这个类方法,然后加上这个装饰器
@method_decorator(csrf_exempt, name="dispatch")
class StudentsView(View):

    def get(self, request, *args, **kwargs):
        print("get")
        return HttpResponse("GET")

    def post(self, request, *args, **kwargs):

        return HttpResponse("POST")

    def put(self, request, *args, **kwargs):

        return HttpResponse("PUT")

    def delete(self, request, *args, **kwargs):

        return HttpResponse("DELETE")


(7)以上内容梳理_略

# 直接上图

【武sir】django rest framework源码和实战_day01(上)_第21张图片


【补充知识】

# (1)getattr() 反射的使用。

                还得提一点就是比如 getattr(obj, '_negotiator', None),就是返回 obj._negotiator,如果有的话。我们之前说了,如果没这个属性,反射就会报错,这个时候就可以用后面 None 了,意思是说,如果没有这个属性,系统也不报错,而是会返回一个 None。

【武sir】django rest framework源码和实战_day01(上)_第22张图片


# (2)类继承的优先级

【武sir】django rest framework源码和实战_day01(上)_第23张图片


你可能感兴趣的:(django,python,后端)