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. linux系统下使用nginx反向代理asp.net core,并配置免费的https证书

    反向代理是为动态 Web 应用提供服务的常见设置. 反向代理终止 HTTP 请求,并将其转发到 ASP.NET Core 应用. 1.在asp.net core项目中的Startup的Configur ...

  2. python 中问题,包括某些库的问题

    *)TypeError: exceptions must derive from BaseException 原因是raise语句没有写好 raise('value must between 0 an ...

  3. centos如何强行踢掉某登录用户

    linux是一个多用户操作系统,用户可以在不同的地方链接上LINUX服务器. 在系统中我们可以用w或者who来查看用户: [root@7273 ~]# who root pts/0 2019-04-1 ...

  4. git操作:查看分支、删除本地分支和远程分支

    1.查看本地分支:git branch 2.查看远程分支:git branch -r 或 git branch --remote 3.查看本地和远程的所有分支:git branch -a 4.删除本地 ...

  5. Android Scrollview嵌套下listView动态加载数据,解决onScrollChanged执行多次数据重复问题

    这一篇博客和上一篇讲的都是listView的动态加载,但有所不同的是,本篇的listView是嵌套在ScrollView下的,有时候在一个Activity中可能分为好几个模块,由于展示的需要(手机屏幕 ...

  6. Android源码分析(九)-----如何修改Android系统默认时间

    一 : 修改Android系统默认时间 源码路径:frameworks/base/services/java/com/android/server/SystemServer.java 主要变量EARL ...

  7. 分布式session的解决方案

    1.Nginx的ip_hash,对应tomcat的session,由tomcat保存 缺点:一旦tomcat单点挂机,session消失 2.session在tomcat之间复制, 缺点:保存全局se ...

  8. rz上传文件乱码

    问题 使用rz上传文件时,出现乱码,上传失败. 原因 文件中包含控制字符 解决方法 使用 rz -be -b:–binary  用binary的方式上传下载,不解释字符为ascii: -e:–esca ...

  9. javascript 初探

    JS ,前端3剑客之一,控制HTML标签的动作.浏览器通过解释JS代码识别ta要做什么,因为在浏览器操作,所以最好使用谷歌浏览器. 参考: https://www.cnblogs.com/yuanch ...

  10. Nginx Rewrite相关功能-ngx_http_rewrite_module模块指令

    Nginx Rewrite相关功能-ngx_http_rewrite_module模块指令 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.