一、Django中间件的请求周期

我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下:

也就是说,每一个请求都是先通过中间件中的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止,返回到网页上。

二、自定义及注册中间件

1. 创建中间件

在project根目录下创建中间件py文件:

 class RequestExeute(object):
def process_request(self, request):
print('process_request') def process_view(self, request, callback, callback_args, callback_kwargs):
print('process_view') def process_exception(self, request, exception):
"""
当views函数出错时执行
:param request:
:param exception:
:return:
"""
print('process_exception') def process_response(self, request, response):
"""
必须return HttpResponse
:param request:
:param response:
:return:
"""
print('process_response')
return response def process_template_response(self, request, response):
"""
视图函数的返回值中,如果有render方法,才被调用
:param request:
:param response:
:return:
"""
print('process_template_response')
return response

md.py

2. 注册中间件

在settings.py文件中,按照欲执行的顺序注册:

ps. 在1.9及之前的版本中,中间件的关键字为:MIDDLEWARE_CLASSES

MIDDLEWARE_CLASSES = (
'zqxt.middleware.BlockedIpMiddleware',
...其它的中间件
)

三、中间件中方法的执行顺序

1. 正常状况

 from django.shortcuts import HttpResponse
from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
def process_request(self, request):
print('m1.request')
# return HttpResponse('request_m1') def process_view(self, request, callback, callback_args, callback_kwargs):
print('m1.view')
# response = callback(request, *callback_args, **callback_kwargs)
# return response def process_response(self, request, response):
print('m1.response')
return response def process_exception(self, request, exception):
print('m1.process_exception')
return HttpResponse('m1.process_exception') def process_template_response(self, request, response):
"""
视图函数的返回值中,如果有render方法,才被调用
:param request:
:param response:
:return:
"""
print('m1.process_template_response')
return response class M2(MiddlewareMixin):
def process_request(self, request):
print('m2.request') def process_view(self, request, callback, callback_args, callback_kwargs):
print('m2.view')
# response = callback(request, *callback_args, **callback_kwargs)
# return response def process_response(self, request, response):
print('m2.response')
return response def process_exception(self, request, exception):
print('m2.process_exception')
return HttpResponse('m2.process_exception') def process_template_response(self, request, response):
"""
视图函数的返回值中,如果有render方法,才被调用
:param request:
:param response:
:return:
"""
print('m2.process_template_response')
return response

process_request和process_view返回None

执行顺序:

  1. m1.request
  2. m2.request
  3. m1.view
  4. m2.view
  5. m2.response
  6. m1.response

2. 在版本1.10及之后

若process_request返回HttpResponse 对象,则从当前中间件的process_response向前返回

 from django.shortcuts import HttpResponse
from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
def process_request(self, request):
print('m1.request')
return HttpResponse('request_m1') def process_view(self, request, callback, callback_args, callback_kwargs):
print('m1.view')
# response = callback(request, *callback_args, **callback_kwargs)
# return response def process_response(self, request, response):
print('m1.response')
return response def process_exception(self, request, exception):
print('m1.process_exception')
return HttpResponse('m1.process_exception') def process_template_response(self, request, response):
"""
视图函数的返回值中,如果有render方法,才被调用
:param request:
:param response:
:return:
"""
print('m1.process_template_response')
return response class M2(MiddlewareMixin):
def process_request(self, request):
print('m2.request') def process_view(self, request, callback, callback_args, callback_kwargs):
print('m2.view')
# response = callback(request, *callback_args, **callback_kwargs)
# return response def process_response(self, request, response):
print('m2.response')
return response def process_exception(self, request, exception):
print('m2.process_exception')
return HttpResponse('m2.process_exception') def process_template_response(self, request, response):
"""
视图函数的返回值中,如果有render方法,才被调用
:param request:
:param response:
:return:
"""
print('m2.process_template_response')
return response # class RequestExeute(object):
# def process_request(self, request):
# print('process_request')
#
# def process_view(self, request, callback, callback_args, callback_kwargs):
# print('process_view')
#
# def process_exception(self, request, exception):
# """
# 当views函数出错时执行
# :param request:
# :param exception:
# :return:
# """
# print('process_exception')
#
# def process_response(self, request, response):
# """
# 必须return HttpResponse
# :param request:
# :param response:
# :return:
# """
# print('process_response')
# return response
#
# def process_template_response(self, request, response):
# """
# 视图函数的返回值中,如果有render方法,才被调用
# :param request:
# :param response:
# :return:
# """
# print('process_template_response')
# return response

M1的process_request返回HttpResponse

执行顺序:

  1. m1.request
  2. m1.response

process_view与process_request类似:

 from django.shortcuts import HttpResponse
from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
def process_request(self, request):
print('m1.request')
# return HttpResponse('request_m1') def process_view(self, request, callback, callback_args, callback_kwargs):
print('m1.view')
response = callback(request, *callback_args, **callback_kwargs)
return response def process_response(self, request, response):
print('m1.response')
return response def process_exception(self, request, exception):
print('m1.process_exception')
return HttpResponse('m1.process_exception') def process_template_response(self, request, response):
"""
视图函数的返回值中,如果有render方法,才被调用
:param request:
:param response:
:return:
"""
print('m1.process_template_response')
return response class M2(MiddlewareMixin):
def process_request(self, request):
print('m2.request') def process_view(self, request, callback, callback_args, callback_kwargs):
print('m2.view')
# response = callback(request, *callback_args, **callback_kwargs)
# return response def process_response(self, request, response):
print('m2.response')
return response def process_exception(self, request, exception):
print('m2.process_exception')
return HttpResponse('m2.process_exception') def process_template_response(self, request, response):
"""
视图函数的返回值中,如果有render方法,才被调用
:param request:
:param response:
:return:
"""
print('m2.process_template_response')
return response

m1的process_view返回HttpResponse

执行顺序:

  1. m1.request
  2. m2.request
  3. m1.view
  4. m2.response
  5. m1.response

3. 在版本1.10之前

若process_request返回HttpResponse 对象,则当前中间件之后的process_request都不会执行,而从最后一个中间件的process_response向前返回

参考资料:

1. Python之路【第十六篇】:Django【基础篇】

2. http://code.ziqiangxuetang.com/django/django-middleware.html

Django—middleware的更多相关文章

  1. Django Middleware简介

    1      前言 Django使用非常熟练了,各种API接口不在话下,全都搞定.为方便定位问题在每个API接口的的开始和返回的地方都加上了log打印,记录入参和返回值. 但是这样有一个问题,需要每个 ...

  2. Django MiddleWare初识

    一.Django 中间件介绍 中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定 ...

  3. Django 中CSRF中间件 'django.middleware.csrf.CsrfViewMiddleware',

    1.Django中CSRF中间件的工作原理及form表单提交需要添加{% csrf_token %}防止出现403错误 CSRF # 表示django全局发送post请求均需要字符串验证功能:防止跨站 ...

  4. Django middleware (中间件)

    关于中间价: django 中的中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 在django项目的settings中,有一个 MIDDLE ...

  5. django middleware介绍

    Middleware Middleware是一个镶嵌到django的request/response处理机制中的一个hooks框架.它是一个修改django全局输入输出的一个底层插件系统. 每个中间件 ...

  6. 【转】Django Middleware

    Django 处理一个 Request 的过程是首先通过中间件,然后再通过默认的 URL 方式进行的.我们可以在 Middleware 这个地方把所有Request 拦截住,用我们自己的方式完成处理以 ...

  7. Django Middleware 之 SessionMiddleware

    Django版本:1.7.11 先放源码: class SessionMiddleware(object): def __init__(self): engine = import_module(se ...

  8. Django分析之Middleware中间件

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

  9. Django 源码小剖: 初探中间件(middleware)

    因为考虑到文章的长度, 所以 BaseHandler 的展开被推迟了. 在 BaseHandler 中隐藏着中间件的信息, 较常见的 SessionMiddleware 就已经默认安装.  BaseH ...

随机推荐

  1. 子元素margin-top为何会影响父元素?

    子元素margin-top为何会影响父元素? 引用地址:https://blog.csdn.net/sinat_27088253/article/details/52954688 2016年10月28 ...

  2. Pycharm与github的秘密

    GIT介绍 GIT文章请看老男孩教育-银角大王的博客: http://www.cnblogs.com/wupeiqi/articles/7295372.html Git 是一个开源的分布式版本控制软件 ...

  3. 02-线性结构3 Reversing Linked List (25 分)

    Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elem ...

  4. my.等级限制

    1.20190405 “春之恋曲 4月5日双平台新服开服公告”,20190426  上去新建了一个号  发现等级限制是 66级(2天后开启新等级) 20190412 “胭脂雪 4月12日双平台新服开服 ...

  5. vue移动端更改手机物理按键返回问题

    又是一天见面的日子,春季盎然~ 已经无法在继续抒情下去了,写作水平骤降!! 今天记录下应用cordva+vue生成的apk 在手机物理返回时遇到的问题: 前提说~~应用vue,我们可以自定义上一路径和 ...

  6. Service启动流程

    Service启动流程从整个宏观上来看,它的模型如下 startService启动流程时序图 Activity中使用的startService方法是定义在Context的抽象类中,它的真正实现者是Co ...

  7. js需要清楚的内存模型

    原型 原型重写 原型继承 组合方式实现继承 函数作用域链

  8. 关于myeclipse加载building workspace卡顿的解决办法

    在MyEclipse的使用中,在建立新文件或者改动代码后,经常会出现building workspace半天卡顿不动的情况,如果开的程序过多,经常会发生失去响应,电脑要是再烂点,直接死机的情况也常有发 ...

  9. Maven的目录结构和常用命令

    一.Maven项目的目录结构  1.顶级目录结构   src:该目录主要存放的是项目的源代码文件. target:该目录是项目编译后产生的一个目录,主要存放的是编译后的.class文件. pom.xm ...

  10. Handling of asynchronous events---reference

    http://www.win.tue.nl/~aeb/linux/lk/lk-12.html 12. Handling of asynchronous events One wants to be n ...