django middleware介绍
Middleware
Middleware是一个镶嵌到django的request/response处理机制中的一个hooks框架。它是一个修改django全局输入输出的一个底层插件系统。
每个中间件组件负责一些特定的功能,比如说 Django包含一个 AuthenticationMiddleware的中间间,使用sessions将用户和请求联系在一起( that associates users with requests using sessions.)。
这篇文章解释了中间件如何工作,如果激活中间件,如何编写自己的中间件。django有很多内建的中间件,详细内容查看内建中间件附录。
激活中间件
要想激活中间件,需要在settings文件中的 MIDDLEWARE_CLASSES下增加。在 MIDDLEWARE_CLASSES中,每个中间件以一个字符串的形势保存。比如,下面是默认创建工程的中间件 MIDDLEWARE_CLASSES内容:
MIDDLEWARE_CLASSES = ['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'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_CLASSES可以为空,但是强烈建议至少包含 CommonMiddleware这个中间件。
中间件在MIDDLEWARE_CLASSES中是有顺序的,因为中间件之间有相互依赖关系。比如说AuthenticationMiddleware 在session中保存认证的用户信息,因此,它必须在 SessionMiddleware之后,详细的内容可以参考Middleware ordering。
Hooks和application的顺序
在请求阶段,调用views之前,django按照MIDDLEWARE_CLASSES中定义的顺序从上到下调用中间件。有两个hooks:
- process_request()
- process_view()
在响应阶段,调用views之后,中间件被从下到上反向调用,有三个hooks:
- process_exception() (只有当view中raise一个例外时)
- process_template_response() (只有view中返回template时)
- process_response()
如果你喜欢,可以把它比作洋葱,每个中间件就是洋葱的一层皮。
每个hooks在下面描述:
编写你自己的中间件
写一个自己的中间件很简单,每个中间件就是一个普通的python类,包含下面的一个或多个方法:
1) process_request()
process_request(request)
其中request是HttpRequest对象,process_request() 将会在每个request被决定使用哪个view之前调用,它会返回None或者一个HttpResponse对象。
- 如果返回None,django会继续执行其他中间件的process_request(), 然后是process_view() ,然后是恰当的view函数。
- 如果返回HttpResponse对象,它就直接返回了,不再执行其他中间件,view等。
2) process_view()
process_view(request, view_func, view_args, view_kwargs)
其中request是HttpRequest 对象, view_func是django要使用的view函数 (它是实际的函数对象,而不是函数名字的字符串) view_args是view函数的列表参数, view_kwargs是view函数的字典参数。 view_args和 view_kwargs都不需要包含request这个参数。
process_view()就在django调用view函数之前被调用。
与process_request()相同,process_request()会返回None或者一个HttpResponse对象。
- 如果返回None,django会继续执行其他中间件的process_view(),然后是恰当的view函数。
- 如果返回HttpResponse对象,它就直接返回了,不再执行其他中间件,view等。
Note
尽量避免使用process_request 或者process_view 来访问request.POST。但是 CsrfViewMiddleware中间件是一个例外,它提供 csrf_exempt() 和 csrf_protect() 两个装饰器来解决此问题。
Accessing request.POST inside middleware from process_request orprocess_view will prevent any view running after the middleware from being able to modify the upload handlers for the request, and should normally be avoided.
The CsrfViewMiddleware class can be considered an exception, as it provides the csrf_exempt() and csrf_protect() decorators which allow views to explicitly control at what point the CSRF validation should occur.
3) process_template_response()
process_template_response(request, response)
其中request 是 HttpRequest 对象, response 是一个由django view或者中间件返回的TemplateResponse 对象。
process_template_response()在view使用render渲染一个模版对象完成之后被调用,它必须返回一个render 方法执行后的response对象,它可以修改view中返回的 response.template_name 和 response.context_data,或者为view返回的模板增加一个商标等等。
你不需要明确的渲染响应,当所有的template响应中间件处理完成后会被自动渲染。
带有process_template_response()的中间件将会被自下而上反向执行。
4) process_response()
process_response(request, response)
其中request是 HttpRequest 对象, response 是一个django view或者中间件返回的 HttpResponse 或者StreamingHttpResponse对象。
process_response()在所有的响应被返回到浏览器之前执行。
它必须返回一个 HttpResponse 或者StreamingHttpResponse 对象,它可以修改response, 或者为 HttpResponse 或StreamingHttpResponse增加一个商标等。
它不像 process_request() 和process_view() 方法可能会被跳过(在他之前有人返回了HttpResponse对象), process_response()方法一定会被执行。因此,你的process_response() 方法不能依赖于你的process_request()方法。
最后,记住在响应阶段,中间件会被反向执行,你最后在 MIDDLEWARE_CLASSES定义的中间件将会被最先执行。
处理流式响应
不同于HttpResponse,StreamingHttpResponse沒有content属性,因此中间件不能认为所有的响应都有content 属性,如果想要访问content,需要测试流式响应:
if response.streaming:
response.streaming_content = wrap_streaming_content(response.streaming_content)
else:
response.content = alter_content(response.content)
Note
streaming_content 被假定为太大而不能存放在内存中, 响应中间件可以将它包裹在一个生成器中,但是必须不能消费它,通常如下所示:
def wrap_streaming_content(content):
for chunk in content:
yield alter_content(chunk)
5) process_exception()
process_exception(request, exception)
其中request 是 HttpRequest 对象. exception是view函数中raise的Exception对象。
Django当view函数raise一个例外时调用process_exception() 。process_exception()返回None 或者HttpResponse 对象
- 如果返回 HttpResponse 对象,template response 和response中间件会被应用, 然后在浏览器中返回结果,否则,默认的例外处理将会被使用。
再说一遍,包含process_exception的中间件将会被反向执行,如果下面的中间件返回一个response,上面的中间间将不会被执行。
6) init()
大多数处理 process_* 方法的中间件都不需要自定义构造函数,如果你确实需要有一些全局的内容需要定义也可以使用,但是注意下面两点:
- Django初始化中间件不会包含任何参数,所以不能在__init__ 要求任何参数;
- 不像process_* 方法在每次请求时调用,__init__方法只会在web server首次处理请求的时候调用。
标记中间件为不可用
有时候在运行的时候决定哪个中间件是否可用是十分必要的,这种情况下你的自定义中间件__init__方法可以 raise django.core.exceptions.MiddlewareNotUsed,django将会移除中间件,并且报一个日志,如果DEBUG打开的话,可以在django.request logger里看到。(1.8之前的版本,MiddlewareNotUsed不会在日志中体现)
7)指导意见
- 中间件不继承;
- 中间件写在哪里都行,只需要加到MIDDLEWARE_CLASSES settings中。
来源: https://docs.djangoproject.com/en/1.9/topics/http/middleware/
django middleware介绍的更多相关文章
- Django Middleware简介
1 前言 Django使用非常熟练了,各种API接口不在话下,全都搞定.为方便定位问题在每个API接口的的开始和返回的地方都加上了log打印,记录入参和返回值. 但是这样有一个问题,需要每个 ...
- Django框架介绍之一
这片博文就是对django有个大概的了解,通俗的说,就是先让django跑起来. django安装 在linux上安装如下: 源码安装: tar -zxvf Django-1.9.13.tar.gz ...
- Django MiddleWare初识
一.Django 中间件介绍 中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定 ...
- django框架介绍安装-自写框架
原文链接:https://www.cnblogs.com/maple-shaw/p/8862330.html Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户 ...
- Django 入门介绍
Django介绍 Django框架是PythonWeb三大主流框架之一,以其功能强大全面而受到众多开发者追捧,现如今Django已经更新到3版本,但是并不推荐使用,更多建议使用1版本. Django版 ...
- django中间件介绍
在学习django中间件之前,先来认识一下django的生命周期,如下图所示: django生命周期:浏览器发送的请求会先经过wsgiref模块处理解析出request(请求数据)给到中间件,然后通过 ...
- Django 框架介绍
Django 框架介绍 MVC框架和MTV框架 简单了解一下什么是MVC框架.MVC(Model View Controller),是模型(model)-视图(view)-控制器(controller ...
- python Django 中间件介绍
我们一直都在使用中间件,只是没有注意到而已,打开Django项目的Settings.py文件,看到下面的MIDDLEWARE配置项,django默认自带的一些中间件: MIDDLEWARE = [ ' ...
- Django settings介绍
""" Django settings for macboy project. Generated by 'django-admin startproject' usin ...
随机推荐
- React 之form表单、select、textarea、checkbox使用
1.案例如下 import React from 'react'; /** * 非约束性组(类似defaultValue等属性,不可以程序修改): <input type="text& ...
- OpenFlow/SDN 的缘起与发展
目录 文章目录 目录 从虚拟机动态迁移对大二层网络的需求说起 OpenFlow 起源 从 OpenFlow 扩展为 SDN OpenFlow 的应用场景 网络虚拟化 – FlowVisor 负载均衡 ...
- nginx禁止指定的user_agent访问
#禁止指定user_agent(浏览器标识)if ($http_user_agent ~ 'curl|baidu'){ return 403;} if ($http_user_agent ~* 'cu ...
- linux配置多个ip
linux配置多个ip /sbin/ifconfig eth0:1 172.19.121.180 broadcast 172.19.121.255 netmask 255.255.255.0 up ...
- delphi 导出excel
Var FExcel:OleVariant; //excel应用程序 FWorkBook :OleVariant; //工作表 Temsheet:OleVariant; //工作薄 FPicture: ...
- 【Qt开发】QTextEdit 外观属性设置
一.给QTextEdit添加背景图片,有下面两种方法: QTextEdit* iEdit = new QTextEdit(); 1:使用样式表: iEdit->setStyleSheet(&q ...
- (转).net中的session与cookies区别及使用方法
cookie数据存放在客户的浏览器上,session数据放在服务器上,cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session 先介绍一 ...
- Python 爬取SeeBug poc
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2017-08-24 21:42:52 # @Author : EnderZhou (z ...
- 最长上升(不下降)子序列(LIS) 不同求解方法(动规、贪心)
给定一个序列,求出它的最长上升子序列或者是最长不下降子序列的长度 或者输出这个子序列 一.动态规划 O(n^2) 1.求长度 首先来讨论最长上升子序列的情况,即子序列是严格上升的 假如我们以dp[i] ...
- Mysql数据库表结构设计准则
一:动静分离 解释:最好做好静态表和动态表的分离.这里解释一下静态表和动态表的含义,静态表:存储着一些固定不变的资源,比如城市/地区名/国家(静态表一定要使用缓存).动态表:一些频繁修改的表 二:关于 ...