Django教程笔记之中间件middleware详解


Posted in Python onAugust 01, 2018

中间件介绍

中间件顾名思义,是介于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的执行顺序正好相反,如下图所示:

Django教程笔记之中间件middleware详解

也就是说,每一个请求都是先通过中间件中的 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官方文档以及网络上的一些教程,这里也非常感谢这些前辈的分享。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python socket编程实例详解
May 27 Python
python爬虫正则表达式之处理换行符
Jun 08 Python
查找python项目依赖并生成requirements.txt的方法
Jul 10 Python
Win8下python3.5.1安装教程
Jul 29 Python
opencv实现静态手势识别 opencv实现剪刀石头布游戏
Jan 22 Python
Python如何获得百度统计API的数据并发送邮件示例代码
Jan 27 Python
用sqlalchemy构建Django连接池的实例
Aug 29 Python
Python之数据序列化(json、pickle、shelve)详解
Aug 30 Python
numpy.array 操作使用简单总结
Nov 08 Python
使用python远程操作linux过程解析
Dec 04 Python
Python之字符串的遍历的4种方式
Dec 08 Python
python中Tkinter 窗口之输入框和文本框的实现
Apr 12 Python
flask框架中勾子函数的使用详解
Aug 01 #Python
flask中过滤器的使用详解
Aug 01 #Python
Python拼接微信好友头像大图的实现方法
Aug 01 #Python
Python Flask前后端Ajax交互的方法示例
Jul 31 #Python
Python常见内置高效率函数用法示例
Jul 31 #Python
Python使用jsonpath-rw模块处理Json对象操作示例
Jul 31 #Python
flask-socketio实现WebSocket的方法
Jul 31 #Python
You might like
php 安全过滤函数代码
2011/05/07 PHP
php 网上商城促销设计实例代码
2012/02/17 PHP
slice函数的用法 之不错的应用
2006/12/29 Javascript
7款吸引人眼球的jQuery/CSS3特效实例分享
2013/04/25 Javascript
JS弹出可拖拽可关闭的div层完整实例
2015/02/13 Javascript
EasyUi中的Combogrid 实现分页和动态搜索远程数据
2016/04/01 Javascript
JS中正则表达式只有3种匹配模式(没有单行模式)详解
2016/07/28 Javascript
jQuery中的AjaxSubmit使用讲解
2016/09/25 Javascript
JavaScript实现256色转灰度图
2017/02/22 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图和饼图的组合图效果示例【附demo源码下载】
2017/03/09 Javascript
angularjs ui-router中路由的二级嵌套
2017/03/10 Javascript
vue+express 构建后台管理系统的示例代码
2018/07/19 Javascript
vue中使用vue-cli接入融云实现即时通信
2019/04/19 Javascript
js定义类的方法示例【ES5与ES6】
2019/07/30 Javascript
vue日历/日程提醒/html5本地缓存功能
2019/09/02 Javascript
js实现无刷新监听URL的变化示例代码详解
2020/06/03 Javascript
[33:15]2018DOTA2亚洲邀请赛3月30日 小组赛B组 VP VS Mineski
2018/03/31 DOTA
[49:15]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第二场 1月19日
2021/03/11 DOTA
python在Windows8下获取本机ip地址的方法
2015/03/14 Python
初步理解Python进程的信号通讯
2015/04/09 Python
Python 中pandas.read_excel详细介绍
2017/06/23 Python
pyqt5实现登录界面的模板
2020/05/30 Python
PyQt5固定窗口大小的方法
2019/06/18 Python
django之对FileField字段的upload_to的设定方法
2019/07/28 Python
详解python metaclass(元类)
2020/08/13 Python
Python绘制词云图之可视化神器pyecharts的方法
2021/02/23 Python
为有想象力的人提供的生活方式商店:Firebox
2018/06/04 全球购物
LORAC官网:美国彩妆品牌
2019/08/27 全球购物
城市轨道专业个人求职信范文
2013/09/23 职场文书
信息科学与技术专业求职信范文
2014/02/20 职场文书
工作会议主持词
2014/03/17 职场文书
公司介绍信范文
2015/01/31 职场文书
升学宴学生致辞
2015/09/29 职场文书
2019最新激励员工口号大全!
2019/06/28 职场文书
海贼王十大潜力果实,路飞仅排第十,第一可毁世界(震震果实)
2022/03/18 日漫
Smart 2 车辆代号 HC11 全新谍照曝光
2022/04/21 数码科技