zoukankan      html  css  js  c++  java
  • Django 分析(一)Requst、Middleware 和 Response 数据流

    0. 前言

    • 通过 Django 编写 HTTP 接口时,我们需要指定 URL、Model 和 Views 函数(或者指定 RESTBaseView 对象解析参数和编写逻辑)
    • 编写逻辑时的基本思路就是解析 Request 对象 → 逻辑处理 → 返回 Response 对象
    • RESTBaseView 对象封装了这一逻辑,我们只需要指定参数、解析方、处理逻辑和返回值即可

    1. 基本概念 

    1.1 WSGI

    • WSGI:是 python web 开发的标准,类似于协议
      • 它是服务器程序和应用程序的一个约定,规定了各自使用的接口和功能,以便二和互相配合
      • WSGI 处理程序充当服务器(Apache、Nginx 等)和应用程序(Django)之间的守门员
    • Python web开发中,服务端程序可分为2个部分:
      • 服务器程序(用来接收、整理客户端发送的请求)
      • 应用程序(处理服务器程序传递过来的请求)
    • 在开发应用程序的时候,我们会把常用的功能封装起来,成为各种框架,比如Flask、Django 和 Tornado(使用某框架进行 web 开发,相当于开发服务端的应用程序,处理后台逻辑)
    • 但是,服务器程序和应用程序互相配合才能给用户提供服务,而不同应用程序(不同框架)会有不同的函数、功能
    • 此时,我们就需要一个标准,让服务器程序和应用程序都支持这个标准,那么,二者就能很好的配合了

    1.2 中间件

    • 中间件被用在 Django 项目中的许多关键功能中,例如:
      • 使用 CSRF 中间件来防止跨站请求伪造攻击
      • 处理会话数据
      • 身份验证和授权是使用中间件完成的
    • 服务器和应用程序之间是中间件,可以将中间件视为一系列双向过滤器:
      • 要么对来自用户的数据进行预处理,然后发送给应用
      • 要么在应用将响应负载返回给用户之前,对结果数据进行一些最终的调整
    MIDDLEWARE_CLASSES = (
        'django.middleware.common.CommonMiddleware',
        'session_pyclient.account.django_middleware.AccountSessionMiddleware',
        # 'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'django.middleware.security.SecurityMiddleware',
    )
    • 中间件可以定义五个方法,分别是:(主要的是 process_request 和 process_response)

    process_request(self,request)
    process_view(self, request, view_func, view_args, view_kwargs)
    process_template_response(self,request,response)
    process_exception(self, request, exception)
    process_response(self, request, response) 
    • 以上方法的返回值可以是 None 或一个 HttpResponse 对象:
      • 如果是 None,则继续按照 Django 定义的规则向后继续执行
      • 如果是 HttpResponse 对象,则直接将该对象返回给用户
    from django.utils.deprecation import MiddlewareMixin
    
    
    class MD1(MiddlewareMixin):
    
        def process_request(self, request):
            print("MD1里面的 process_request")
    
        def process_response(self, request, response):
            print("MD1里面的 process_response")
            return response
    
        def process_view(self, request, view_func, view_args, view_kwargs):
            print("-" * 80)
            print("MD1 中的process_view")
            print(view_func, view_func.__name__)
    
    
    class MD2(MiddlewareMixin):
        def process_request(self, request):
            print("MD2里面的 process_request")
            pass
    
        def process_response(self, request, response):
            print("MD2里面的 process_response")
            return response
    
        def process_view(self, request, view_func, view_args, view_kwargs):
            print("-" * 80)
            print("MD2 中的process_view")
            print(view_func, view_func.__name__) 
    • process_request:有一个参数,就是 request,这个 request 和 Views 函数中的 request 是一样的
      • 中间件的 process_request 方法是在执行 Views 函数之前执行的
      • 当配置多个中间件时,会按照 MIDDLEWARE 中的注册顺序,也就是列表的索引值,从前到后依次执行的。
      • 不同中间件之间传递的 request 都是同一个对象
      • 返回值可以是 None 也可以是 HttpResponse 对象。返回值是 None 的话,按正常流程继续走,交给下一个中间件处理
      • 如果是 HttpResponse 对象,Django 将不执行视图函数,而将相应对象返回给浏览器
    • process_response:有两个参数,一个是 request,一个是 response。
      • request 就是上述例子中一样的对象,response 是 Views 函数返回的 HttpResponse 对象。该方法的返回值也必须是 HttpResponse 对象
      • 中间件的 process_response 方法是按照 MIDDLEWARE 中的注册顺序倒序执行的
      • 该方法的返回值也必须是 HttpResponse 对象
    • process_view:该方法有四个参数:
      • request 是HttpRequest对象
      • view_func:是Django即将使用的 Views 函数
      • view_args:是将传递给 Views 的位置参数的列表
      • view_kwargs:是将传递给 Views 的关键字参数的字典。 view_args 和 view_kwargs 都不包含第一个 Views 参数(request)
      • process_view 方法是在 process_request 之后,视图函数之前执行的,执行顺序按照 MIDDLEWARE 中的注册顺序从前到后顺序执行的
      • Django 会在调用 Views 函数之前调用 process_view 方法。它应该返回 None 或一个 HttpResponse 对象
        • 如果返回 None,Django 将继续处理这个请求,执行任何其他中间件的 process_view 方法,然后在执行相应的 Views
        • 如果它返回一个 HttpResponse 对象,Django 不会调用适当的 Views 函数。 它将执行中间件的 process_response 方法并将应用到该 HttpResponse 并返回结果
    • process_exception:有两个参数,一个是 request,一个是 exception。exception 是视图函数异常产生的 Exception 对象
      • 这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个 None 也可以是一个 HttpResponse 对象
        • 如果是 HttpResponse 对象,Django 将调用模板和中间件中的 process_response 方法,并返回给浏览器,否则将默认处理异常
        • 如果返回一个 None,则交给下一个中间件的 process_exception 方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行
    • process_template_response:用的比较少,暂不介绍
    • 基本过程如下:

    2. 数据流

    • 启动一个 Django 项目的时候,需要执行 'runserver' 的操作,而 ruserver 是使用 Django 自带的的 Web Server,主要用于开发和调试中,而在正式的环境中,一般会使用 Nginx+uwsgi 模式
    • 无论是哪种方式,当启动一个项目,都会做两件事:
      • 首先创建一个WSGIServer类的实例,接受用户的请求
      • 然后当一个用户的 HTTP 请求到达的时,为用户初始化一个 WSGIHandler,用于处理用户请求与响应,这个 Handler 是处理整个 Request 的核心
    • Handler 从请求到相应处理流程如下:

    3. 参考文献

  • 相关阅读:
    2017ccpc全国邀请赛(湖南湘潭) E. Partial Sum
    Codeforces Round #412 C. Success Rate (rated, Div. 2, base on VK Cup 2017 Round 3)
    2017 中国大学生程序设计竞赛 女生专场 Building Shops (hdu6024)
    51nod 1084 矩阵取数问题 V2
    Power收集
    红色的幻想乡
    Koishi Loves Segments
    Wood Processing
    整数对
    Room and Moor
  • 原文地址:https://www.cnblogs.com/wangao1236/p/10900301.html
Copyright © 2011-2022 走看看