django——中间件

django——中间件

  • 中间件介绍
  • 自定义中间件
  • 基于django中间件设计项目功能

中间件的介绍

什么是中间件

中间件是介于request与response处理之间的一道处理过程,可以在全局上改变django的输入与输出。由于其影响的是全局,所以需要谨慎使用,使用不当会影响性能。

中间件的本质

中间件的本质就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

中间件的作用

修改HttpResquest、HttpResponse

中间件的使用场景

全局相关的功能:
全局用户身份校验 全局用户黑名单校验 全局用户访问频率校验

Django默认的中间件

django默认自带七个中间件 每个中间件都有各自负责的功能

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    # xss脚本过滤,一些安全设置

    'django.contrib.sessions.middleware.SessionMiddleware',
	# session支持中间件,在每次用户访问django项目时,添加session对每一个浏览器

    'django.middleware.common.CommonMiddleware',
	# 通用组件,比如为路由添加末尾斜杠

    'django.middleware.csrf.CsrfViewMiddleware',
	# 防跨站请求伪造令牌,为客户端添加csrf_token密钥,在表单提交时需提交该值

    'django.contrib.auth.middleware.AuthenticationMiddleware',
	# admin用户组件,每个request对象都会被添加admin下的user属性

    'django.contrib.messages.middleware.MessageMiddleware',
		# 消息中间件 展示一些后台消息给前端

    'django.middleware.clickjacking.XFrameOptionsMiddleware',
	# 防止欺骗点击攻击出现;自身页面被嵌入到他人页面中,点击欺骗 
]

MIDDLEWARE配置项是一个列表(列表是有序的,记住这一点,后面你就知道为什么要强调有序二字),列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。

自定义中间件

django支持自定义中间件可以有5个方法

process_request(self,request)
process_view(self, request, view_func, view_args, view_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)

自定义中间件的基本使用

1.创建一个任意名称的文件夹

2.在该文件夹内创建一个任意名称的py文件

3.在该py文件内编写中间件类

4.配置文件中注册

# 步骤二创建的py文件
from django.utils.deprecation import MiddlewareMixin    #中间件类必须继承
from django.shortcuts import HttpResponse,redirect,render

class MyMdd1(MiddlewareMixin):
    def process_request(self, request):
        print('from MyMdd1 process_request')

    def process_response(self, request, response):
        print('from MyMdd1 process_response')
        return response  # response就是视图函数返回给客户端的数据

# settings.py
MIDDLEWARE = [
    # 注册自定义中间件
    'app01.mymiddleware.mymdd.MyMdd1',
    'app01.mymiddleware.mymdd.MyMdd2',
]

中间件的五个方法理解

①process_request(self,request):

def process_request(self, request):
    print('from MyMdd1 process_request')
    return HttpResponse('from MyMdd1 process_request')
作用:
	执行主路由之前被掉用,在每个请求上调用,返回None(请求通过)或者HttpResponse对象(请求不通过)

用途:过滤请求

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

def process_view(self,request,view_func, view_args, view_kwargs):
    # print(view_func)  # 即将要执行的视图函数名
    # print(,view_args)  # 传给视图函数的位置参数
    # print(view_kwargs)  # 传给视图函数的关键字参数
    print('from MyMdd2 process_view')
    
作用:
	callback:为视图函数;callback_args:视图函数的位置参数,
    callback_kwargs:视图函数的关键字参数;
    调用视图之前被调用,在每个请求上调用,返回None(请求通过)或者HttpResponse对象(请求不通过)
    
用途:用于代码层面的替换和过滤,这个方法可以拿到视图函数的参数   

③process_template_response(self,request,response)

def process_template_response(self,request,response):
    print('from MyMdd2 process_template_response')
    return response
作用:
	在视图函数执行完毕,且视图函数返回的对象中包含render方法时被调用;该方法需要返回实现了render方法的响应对象

④process_exception(self, request, exception)

def process_exception(self,request,exception):
    print(exception)
    print('from MyMdd2 process_exception')
作用:
	处理过程中抛出异常时被调用,返回一个HttpResponse对象

用途:
    用于一般用于捕获发生的异常,并将其邮件发送给开发人员

⑤process_response(self, request, response)

def process_response(self, request, response):     
    print('from MyMdd1 process_response')
    return response  # response就是视图函数返回给客户端的数据

1.响应走的时候会按照配置文件中注册了的中间件从下往上依次执行每一个中间件里process_response方法、如果没有则直接跳过
2.该方法有两个形参request和response 并且默认情况下应该返回response
3.如果该方法自己返回了HttpResponse对象,那么响应会替换成该HttpResponse对象数据,而不再是视图函数想要返回给客户端的数据    

注:中间件中的大多数方法在返回None时表示忽略当前操作进入下一项事件,当返回HttpResponse对象时,表示此请求结束,直接返回给客户端

基于django中间件设计项目功能

importlib模块:可以通过字符串的形式导入模块

常规的导入方式

方式1:import  句式

方式2:from ... import ... 句式
from bbb import b
from bbb.b import name  # 可以直接导变量数据
print(b)  # <module 'bbb.b' from '/Users/jiboyuan/PycharmProjects/day64_1/bbb/b.py'>
print(b.name)

字符串导入方式

import importlib
module_path = 'bbb.b'
res = importlib.import_module(module_path)
print(res.name)
module_path1 = 'bbb.b.name'
importlib.import_module(module_path1)  # 不可以 最小导入单位是模块文件级别

​ 以发送提示信息为需求编写功能的案例

方式1:简单的函数式封装

方式2:配置文件插拔式设计:

# settings
NOTIFY_FUNC_LIST = [
    'notify.qq.QQ',
    'notify.email.Email',
    'notify.msg.Msg',
    'notify.weixin.WeiXin',
]
# __init__
import settings
import importlib
def send_all(msg):
    # 1.循环获取配置文件中字符串信息
    for str_path in settings.NOTIFY_FUNC_LIST:  # 'notify.qq.QQ'
        # 2.切割路径信息
        module_path, class_str_name = str_path.rsplit('.', maxsplit=1)  # ['notify.qq','QQ']
        # 3.根据module_path导入模块文件
        module = importlib.import_module(module_path)  # from day64.notify import qq
        # 4.利用反射获取模块文件中对应的类名
        class_name = getattr(module, class_str_name)  # Email  Msg  QQ
        # 5.实例化
        obj = class_name()
        # 6.调用发送消息的功能
        obj.send(content)
posted @   Nirvana*  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
点击右上角即可分享
微信分享提示