Python Django中间件使用原理及流程分析


Posted in Python onJune 13, 2020

一、什么是Django中间件

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

说的直白一点是中间件就是帮我们程序员在视图函数执行之前和执行之后都可以一些额外的操作,它是一个自定义的类,类中定义了几个方法,Django框架会在请求的特定时间去执行这些方法。

二、Django中间件的定义规则

1、 自定义中间件的规则

(1)要继承MIDDLEWAREMIXIN类

from django.utils.deprecation import MiddlewareMixin

(2)要重写父类方法 

父类的五个方法(主要process_request process_response)

(1)process_request(self,request)

*主要方法。请求刚进来时,执行视图函数之前调用。(无return)

1.中间件的process_request方法是在执行视图函数之前执行的

2.当配置中间件时,会按照MIDDLEWARE的注册顺序,也就是列表的索引值,从前到后依次执行的。

3.不同中间件之间传递的request都是同一个对象。

(2)process_view(self,request,view_func,view_args,view_kwargs)

*URL路由匹配成功后,执行视图函数之前调用,拿到视图函数对象,及其所有参数。(无return)

 

'''
process_view(self, request, view_func, view_args, view_kwargs)

request是HttpRequest对象。
view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称作为字符串。)
view_args是将传递给视图的位置参数的列表.
view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。
'''

(3)process_template_response(self,request,response)

 

*很少用。执行了render()渲染方法后调用。(有return)

(4)process_exception(self,request,exception)

 

执行视图函数中遇到异常时调用。(无return)

*该方法有两个参数:

一个是httpresponse对象

一个是视图函数产生的exception对象

这个函数只有在视图函数抛出异常才可以执行,它返回none或者httpresponse对象,如果是httpresponse对象,django将调用模板和中间件中的process_reponse方法,并将返回给浏览器,否则默认处理异常,如果返回none,则交给下一个中间件的process_exception方法来处理执行,它的执行顺序也是按照中间件注册顺序的倒序执行。

(5)process_response(self,request,response)

 

主要方法。执行视图函数结束之后有响应时调用。(有return)

返回值可以是一个NONE,或者HttpResponse对象,如果是none,继续按照django定义的向下执行,交给下个中间件处理,如果返回是Httpresponse对象,django将不执行视图函数,则直接将该对象返回给用户。

(3)将自定义中间件类添加到setting.py文件中的MIDDLEWARE配置项里

setting.py

MIDDLEWARE = [
  'django.middleware.security.SecurityMiddleware',
  'django.contrib.sessions.middleware.SessionMiddleware',
  'django.middleware.common.CommonMiddleware',
  'django.middleware.csrf.CsrfViewMiddleware',
  'django.contrib.auth.middleware.AuthenticationMiddleware',
  'django.contrib.messages.middleware.MessageMiddleware',
  'django.middleware.clickjacking.XFrameOptionsMiddleware',

  # 自定义 在对应app内创建一个 my_middleware.py文件,然后定义类名为Middleware的中间件
  'app.my_middleware.Middleware',
]

# 白名单路径,不需要做登陆就能访问的页面
WHITE_LIST = ['/login/', '/logout/']

MIDDLEWARE是一个列表,列表中是一个个字符串,这些字符串其实是类,也就是中间件。

三、代码实现

my_middleware.py

from django.utils.deprecation import MiddlewareMixin # 导入中间间模块
from django.shortcuts import redirect # 返回页面模块
from middlewareDemo import settings # 导入白名单


class Middleware(MiddlewareMixin): # 认证中间件

  def process_request(self, request):
    """
    请求来之前判断是否已经登录
    :param request:
    :return:
    """
    white_list = settings.WHITE_LIST

    if request.path in white_list:
      return None # 如果是白名单的路径,直接跳过
    if not request.user.is_authenticated: # 获取用户是否登陆
      return redirect('/login/')
  
  def process_response(self, request, response):
    """
    不管是何执行结果,都会返回相应的HttpResonse对象
    :param request:
    :param response:
    :return:
    """
    print('m1.process_response')
    return response

  def process_exception(self, request, exception):
    """
    出现异常才会被调用进行异常处理
    :param request:
    :param exception:
    :return:
    """
    print('m1.process_exception')

四、中间件的使用场景

1.做IP限制

放在中间件类的列表中,阻止某些ip访问;

2.URL访问过滤

如果用户访问的是logo视图(放过)

如果访问其他视图,需要检测是否已经有session,已经有了放行,如果没有返回login,这样就省的在多个视图函数上写装饰器了!

3.缓存

客户端请求来了,中间件去缓存看看有没有数据,有直接返回给用户,没有再去逻辑层执行视图函数

4、CSRF

Django项目中默认启用了csrf保护,每次请求时通过CSRF中间件检查请求中是否有正确token值

五、Django中间件与装饰器的区别

1、Django 中间件:在视图函数执行之前先去进行处理,在视图函数执行之后再去进行收尾工作。不会区分是哪个视图,所有的视图统统一视同仁,都会执行之前进行处理或请求之后进行处理。

在Django创建的时候,Django默认会给我们加6个中间件。“比如session和csrf,在视图函数执行前,我们就需要对它进行处理,可以使用装饰器来做,也可以使用中间件来处理。”

2、装饰器:主要是作用域问题。如果给视图函数上面添加装饰器,它能够保证这个视图的方法在执行之前或执行之后被执行。但是它仅仅适用于哪些视图添加装饰器,那些视图会有这些作用。

如果是做一个普遍的处理,不去区分视图的话,就用middleware避免编写重复功能的代码,本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

可以用于登录时的黑名单验证。

如果需要对特殊视图进行处理,可以使用装饰器。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
教你如何将 Sublime 3 打造成 Python/Django IDE开发利器
Jul 04 Python
简单介绍Python中用于求最小值的min()方法
May 15 Python
Python3.2中Print函数用法实例详解
May 19 Python
Python 迭代器与生成器实例详解
May 18 Python
Python基于动态规划算法解决01背包问题实例
Dec 06 Python
CentOS7.3编译安装Python3.6.2的方法
Jan 22 Python
pygame游戏之旅 添加键盘按键的方法
Nov 20 Python
Python+OpenCv制作证件图片生成器的操作方法
Aug 21 Python
Python socket聊天脚本代码实例
Jan 02 Python
Java ExcutorService优雅关闭方式解析
May 30 Python
踩坑:pytorch中eval模式下结果远差于train模式介绍
Jun 23 Python
Python下划线5种含义代码实例解析
Jul 10 Python
Django QuerySet查询集原理及代码实例
Jun 13 #Python
Python celery原理及运行流程解析
Jun 13 #Python
基于Python实现视频的人脸融合功能
Jun 12 #Python
使用Keras实现简单线性回归模型操作
Jun 12 #Python
Python实现Keras搭建神经网络训练分类模型教程
Jun 12 #Python
简单了解Python变量作用域正确使用方法
Jun 12 #Python
keras 读取多标签图像数据方式
Jun 12 #Python
You might like
PHP学习笔记 (1) 环境配置与代码调试
2011/06/19 PHP
php上传功能集后缀名判断和随机命名(强力推荐)
2015/09/10 PHP
浅谈php中curl、fsockopen的应用
2016/12/10 PHP
PHP中命名空间的使用例子
2019/03/22 PHP
3Z版基于jquery的图片复选框(asp.net+jquery)
2010/04/12 Javascript
javascript实现的HashMap类代码
2014/06/27 Javascript
Javascript核心读书有感之语言核心
2015/02/01 Javascript
jQuery下拉美化搜索表单效果代码分享
2015/08/25 Javascript
JS+CSS实现鼠标滑过时动态翻滚的导航条效果
2015/09/24 Javascript
js中substr,substring,indexOf,lastIndexOf,split,replace的用法详解
2015/11/09 Javascript
jquery中object对象循环遍历的方法
2015/12/18 Javascript
全面解析DOM操作和jQuery实现选项移动操作代码分享
2016/06/07 Javascript
js中用cssText设置css样式的简单方法
2016/09/19 Javascript
JS使用正则表达式获取小括号、中括号及花括号内容的方法示例
2018/06/01 Javascript
vue-router history模式下的微信分享小结
2018/07/05 Javascript
Bootstrap fileinput 上传新文件移除时触发服务器同步删除的配置
2018/10/08 Javascript
js 计算图片内点个数的示例代码
2019/04/04 Javascript
[38:41]2014 DOTA2国际邀请赛中国区预选赛 LGD VS CNB
2014/05/22 DOTA
[01:01:13]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第三场
2018/04/06 DOTA
python实现去除下载电影和电视剧文件名中的多余字符的方法
2014/09/23 Python
在Python中使用正则表达式的方法
2015/08/13 Python
对sklearn的使用之数据集的拆分与训练详解(python3.6)
2018/12/14 Python
Python高级特性与几种函数的讲解
2019/03/08 Python
PyTorch搭建多项式回归模型(三)
2019/05/22 Python
PyQt5实现画布小程序
2020/05/30 Python
Django model重写save方法及update踩坑详解
2020/07/27 Python
全世界最美丽的四星和五星级酒店预订:Prestigia.com
2017/11/15 全球购物
Daniel Wellington官方海外旗舰店:丹尼尔惠灵顿DW手表
2018/02/22 全球购物
Room Mate Hotels美国:西班牙酒店品牌
2018/04/10 全球购物
好军嫂事迹材料
2014/01/15 职场文书
学雷锋月活动总结
2014/04/25 职场文书
小学数学课题方案
2014/06/15 职场文书
病人写给医生的感谢信
2015/01/23 职场文书
爸爸的三轮车观后感
2015/06/16 职场文书
推普标语口号大全
2015/12/26 职场文书
详解Vue项目的打包方式(生成dist文件)
2022/01/18 Vue.js