Django教程笔记之中间件middleware详解
作者:自在逍遥 发布时间:2023-06-18 00:48:33
中间件介绍
中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。
每个中间件都会负责一个功能,例如,AuthenticationMiddleware,与sessions处理相关。
激活中间件
需要在settings.py配置文件中,配置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',
]
当然你也可以不试用任何的中间件,这个可以设置为空。
中间件顺序
一般我们我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下,process request 和 process response的执行顺序正好相反,如下图所示:
也就是说,每一个请求都是先通过中间件中的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止,返回到网页上。
中间件不用继承自任何类(可以继承 object ),下面一个中间件大概的样子:
class CommonMiddleware(object):
def process_request(self, request):
return None
def process_response(self, request, response):
return response
需要用到的几个hook:
process_request()
process_exception() (only if the view raised an exception)
process_template_response()
process_response()
常用的中间件组件:
1. Sessions
2. Authentication
3. CSRF Protection
4. GZipping Content
例如,比如我们要做一个 流量统计
class BlockedIpMiddleware(object):
def process_request(self, request):
...数据库拿access值
access = access+1
...存起来,类似这个原理
这里的代码的功能就是 简单的访问一次加一次,把这个中间件的 Python 路径写到settings.py中
MIDDLEWARE_CLASSES = (
'zjj.middleware.BlockedIpMiddleware',
...其它的中间件
)
Django 会从 MIDDLEWARE_CLASSES 中按照从上到下的顺序一个个执行中间件中的 process_request 函数,而其中 process_response 函数则是最前面的最后执行。
二,再比如,我们在网站放到服务器上正式运行后,DEBUG改为了 False,这样更安全,但是有时候发生错误不能显示错误详情页面,有没有办法处理好这两个事情呢?
普通访问者看到的是友好的报错信息
管理员看到的是错误详情,以便于修复 BUG
当然可以有,利用中间件就可以做到!代码如下:
import sys
from django.views.debug import technical_500_response
from django.conf import settings
class UserBasedExceptionMiddleware(object):
def process_exception(self, request, exception):
if request.user.is_superuser or request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:
return technical_500_response(request, *sys.exc_info())
把这个中间件像上面一样,加到你的 settings.py 中的 MIDDLEWARE_CLASSES 中,可以放到最后,这样可以看到其它中间件的 process_request的错误。
当访问者为管理员时,就给出错误详情,比如访问本站的不存在的页面。
普通人看到的是普通的 404(自己点开看看),而我们却可以看到。
三,分享一个简单的识别手机的中间件,更详细的可以参考这个:django-mobi
MOBILE_USERAGENTS = ("2.0 MMP","240x320","400X240","AvantGo","BlackBerry",
"Blazer","Cellphone","Danger","DoCoMo","Elaine/3.0","EudoraWeb",
"Googlebot-Mobile","hiptop","IEMobile","KYOCERA/WX310K","LG/U990",
"MIDP-2.","MMEF20","MOT-V","NetFront","Newt","Nintendo Wii","Nitro",
"Nokia","Opera Mini","Palm","PlayStation Portable","portalmmm","Proxinet",
"ProxiNet","SHARP-TQ-GX10","SHG-i900","Small","SonyEricsson","Symbian OS",
"SymbianOS","TS21i-10","UP.Browser","UP.Link","webOS","Windows CE",
"WinWAP","YahooSeeker/M1A1-R2D2","iPhone","iPod","Android",
"BlackBerry9530","LG-TU915 Obigo","LGE VX","webOS","Nokia5800")
class MobileTemplate(object):
"""
If a mobile user agent is detected, inspect the default args for the view
func, and if a template name is found assume it is the template arg and
attempt to load a mobile template based on the original template name.
"""
def process_view(self, request, view_func, view_args, view_kwargs):
if any(ua for ua in MOBILE_USERAGENTS if ua in
request.META["HTTP_USER_AGENT"]):
template = view_kwargs.get("template")
if template is None:
for default in view_func.func_defaults:
if str(default).endswith(".html"):
template = default
if template is not None:
template = template.rsplit(".html", 1)[0] + ".mobile.html"
try:
get_template(template)
except TemplateDoesNotExist:
pass
else:
view_kwargs["template"] = template
return view_func(request, *view_args, **view_kwargs)
return None
再举一个本地化的中间件的例子:
class LocaleMiddleware(object):
def process_request(self, request):
if 'locale' in request.cookies:
request.locale = request.cookies.locale
else:
request.locale = None
def process_response(self, request, response):
if getattr(request, 'locale', False):
response.cookies['locale'] = request.locale
就是将cookies中的locale设置给request中的locale,供给后面使用。
这部分参考了django官方文档以及网络上的一些教程,这里也非常感谢这些前辈的分享。
来源:https://blog.csdn.net/alvine008/article/details/50249777


猜你喜欢
- 本文实例讲述了JavaScript日期工具类DateUtils定义与用法。分享给大家供大家参考,具体如下:DateUtils = { &nb
- 导语在CSDN学习的过程中,遇到了爆火的文章是关于刮刮卡的!大家猜猜看是谁写的?我看这文章都特别火,我也感觉挺好玩的,那就寻思用 Pytho
- 本文实例讲述了Python使用Pickle库实现读写序列操作。分享给大家供大家参考,具体如下:简介pickle模块实现了用于对Python对
- 摘要:神经网络的训练的主要流程包括图像输入神经网络, 得到模型的输出结果,计算模型的输出与真实值的损失, 计算损失值的梯度,最后用梯度下降算
- 日常项目中,读取各种配置文件是避免不了的,这里介绍一个能读取多种配置文件的库,viperviper读取ini文件config := vipe
- 而标准的事件触发可以使用dispatchEvent方法。但现在FF5无法触发了A的默认行为了。如下 <!doctype html>
- 函数作用:该函数的作用即按字面意思理解,topk:取数组的前k个元素进行排序。通常该函数返回2个值,第一个值为排序的数组,第二个值为该数组中
- 废话不多说了,直接给大家贴代码了,具体代码如下所示:<!DOCTYPE html><html><head>
- 我们曾经提到,Oyster.com的Python web服务器怎样利用一个巨大的Python dicts(hash table),缓存大量的
- 当我们在终端上(比如Goland)运行gin框架搭建的服务时,会发现输出的日志是可以带颜色的。比如下图中的最后一行,就是请求一个方法时的输出
- 对于array,如2-D的array,如何取指定元素设array为3*10的shapes = array([[ 0, 1, 2, 3, 4,
- 在默认情况下,MySQL搜索不区分大小写(但某些字符集始终区分大小写,如czech)。这意味着,如果你使用col_name LIKE
- 导语:用 Python 读取图片的像素值,然后输出到 Excel 表格中,最终形成一幅像素画,也就是电子版的十字绣了。基本思路实现这个需求的
- 将两个嵌套for循环写成一个列表生成式如,有一个嵌套列表,a=[[1,2],[3,4],[5,6]],要提取列表里的每一个元素用for循环处
- 一、Go interface 介绍interface 在 Go 中的重要性说明interface 接口在 Go 语言里面的地位非常重要,是一
- 1. 现在的日期时间命令是<%=now%> 即可2.ASP取得表格(from)数据输入的方法,是使用一个内置
- 一、引言Pillow,是Python Imaging Library (PIL)的一个分支,用于处理图像。它是Python编程语言中最常用的
- 现在写一篇博客总是喜欢先谈需求或者本内容的应用场景,是的,如果写出来的东西没有任何应用价值,确实也没有实际意义。今天的最早的需求是来自于如何
- 如何截取字符函数在工作中我们经常会遇到某种情况需要截取字符串中某个特定标签之间的内容(爬虫可能用到的较多),适用于很多情况例如字符串形式的x
- 本文实例讲述了MySQL数据库优化之索引实现原理与用法。分享给大家供大家参考,具体如下:索引什么是索引索引用来快速地寻找那些具有特定值的记录