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. 参考文献

Django 分析(一)Requst、Middleware 和 Response 数据流的更多相关文章

  1. Django分析之Middleware中间件

    写了几周的脚本,今天终于开始接触web框架了~学习Python的web框架,那么Django就几乎是必修课了,这次的工作是先打打下手,主要的任务是在setting中添加版本号,在渲染静态css,js的 ...

  2. Django 学习之中间件Middleware

    一.中间件介绍 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好会影响 ...

  3. Django分析之国际化处理

    最近在公司终于开始做web开发了,本以为会是简单的首页之类的小规模项目,结果上来就是一个处理大数据分析的项目,一个关于油品分析的系统,不过我接到的第一个任务是做这个网站的国际化处理,虽然项目还没有上线 ...

  4. Django 详解 中间件Middleware

    Django中间件 还是涉及到django的请求生命周期.middle ware 请求穿过中间件到达url,再经过中间件返回给用户. 简单实例 django项目根目录新建一个Middle文件夹,再新建 ...

  5. Django分析之导出为PDF文件

    最近在公司一直忙着做exe安装包,以及为程序添加新功能,好久没有继续来写关于Django的东西了….难得这个周末清闲,来了解了解Django的一些小功能也是极好的了~ 那今天就来看看在Django的视 ...

  6. django HTTP请求(Request)和回应(Response)对象

    Django使用request和response对象在系统间传递状态.—(阿伦)当一个页面被请示时,Django创建一个包含请求元数据的 HttpRequest 对象. 然后Django调入合适的视图 ...

  7. django restframwork教程之Request和Response

    从这一篇文章开始,我们会覆盖整个REST framwork框架的核心,接下来让我们介绍一些基础的构建块 Request 对象 REST framework 引入了一个扩展HttpRequest的请求对 ...

  8. django系列3.4-- request对象和response对象(未完待续)

    一.request对象 详细信息可以查阅django官方文档 共有五种请求相关的常用值 request.path_info 返回用户访问的url不包括域名 request.method 请求中使用的H ...

  9. Django restful Framework 之Requests and Response 方法

    前言: 本章主要介绍REST framework 内置的必要的功能. Request objects Response objects Status codes Wrapping API views ...

随机推荐

  1. css3贝塞尔曲线过渡动画速率——transition-timing-function:cubic-bezier(n,n,n,n)

    css3过渡动画速率用到的是三阶贝塞尔曲线,曲线有四个点,p0,p1,p2,p3 有几个属性: linear 规定以相同速度开始至结束的过渡效果(等于 cubic-bezier(0,0,1,1)). ...

  2. C#实现UrlEncode (URL编码)

    public static string UrlEncode(string str) { StringBuilder sb = new StringBuilder(); byte[] byStr = ...

  3. navicat2059错误的解决

    1.输入mysql -uroot -p登陆mysql 2.登录成功以后使用ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD ...

  4. ES6 对象的拓展(三)

    一.对象中的属性及方法1.属性属性简写:当对象属性名与属性值变量相同可以简写eg: let [name,age]=['nzc','18']; let obj = { name:name, age:ag ...

  5. Kubernetes port-forward

    命令格式: kubectl port-forward <pod_name> <forward_port> --namespace <namespace> --add ...

  6. JMX——以可视化形式管理与监控正在运行中的Java程序

    简单理解: MBean:管理的最小单元,一个MBean就是一个可以被监控的JavaBean. MBeanServer:一个池子,各个MBean都会注册到该池子中,并且该池子提供一系列的管理.监控API ...

  7. 交叉编译用于生成aarch64指令的GCC (9.2)

    参考 Building GCC as a cross compiler for Raspberry Pi How to Build a GCC Cross-Compiler 环境 PC: ubuntu ...

  8. C语言形参跟实参详解

    形参与实参今天我们来说下c语言形参与实参的区别,形参跟实参理解的话也很简单,但是好多同学关于这个知识点都是一知半解,没有真正的去透彻,一问都知道,但在真正引用的时候还会出现很多问题,而百度的时候又会说 ...

  9. PAT 乙级 1042.字符统计 C++/Java

    题目来源 请编写程序,找出一段给定文字中出现最频繁的那个英文字母. 输入格式: 输入在一行中给出一个长度不超过 1000 的字符串.字符串由 ASCII 码表中任意可见字符及空格组成,至少包含 1 个 ...

  10. axios用法全解

    [前言] 本文介绍下axios用法,希望对大家有所帮助 这里声明一句:请求数据一般放置到哪里?详见下篇文章 [主体] (1)下载 npm i axios --save (2)引入axios模块 方式1 ...