一、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. [Alpha]Scrum Meeting#2

    github 本次会议项目由PM召开,时间为4月2日晚上10点30分 时长25分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写内置问卷(issue#3) 撰写团队贡献分配计划(issue#39) ...

  2. JAVA数据结构--优先队列(堆实现)

    优先队列(堆)的定义 堆(英语:Heap)是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的 ...

  3. windows平台下Android studio开发环境搭建教程

    最近,Google 已宣布,为了简化 Android 的开发力度,以重点建设 Android Studio 工具,到今年年底将停止支持Eclipse等其他集成开发环境 .而随着Android stud ...

  4. 解决执行maven项目出现 SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”. error

    最近再弄maven项目,运行起来没有问题,但是Console控制台会报错,比如说如下的问题异常提示: 由此我们可以看出,报出错误的地方主要是slf4j的jar包,而故障码中“Failed to loa ...

  5. 后缀自动机 && 题目

    因为明天要讲解后缀自动机了,所以只能抱抱佛脚,临时做做题目.其实很久以前看过,但是不太懂,看的是clj的原文,不太懂.现在只能临时看看是怎么弄的,应付下. ---------------------- ...

  6. 设置开机自动运行vncserver

    a. 在/etc/rc.d/rc.local文件中加入下面行   /etc/init.d/vncserver startb. 编辑/etc/sysconfig/vncservers   VNCSERV ...

  7. 将Mysql的一张表导出至Excel格式文件

    将Mysql的一张表导出至Excel格式文件 导出语句 进入mysql数据库,输入如下sql语句: select id, name, age from tablename into outfile ' ...

  8. hibernate 学习笔记3

    1. 多对多关联: 在双方都要用一个类型为Set的属性保存对方的信息,并在映射配置文件中指定这个属性的名字,并指定中间表.还需要通过<key column=””>来指定自己在中间表中对应的 ...

  9. js中的特殊符号含义

    一. !! js中的!! var o ={flag:4}; var test = !!o.flag; console.log(test);  // true 二.~~,<< (~~(Mat ...

  10. 快速删除node_modules目录

    当node项目需要重新安装依赖,并且需要删除原有的node_modules目录时,windows下删除该目录比较麻烦的,所以我就在网上找了个npm包,名字叫做 rimraf 安装步骤: npm ins ...