首页 > 其他分享 >django中间件

django中间件

时间:2022-12-26 18:22:59浏览次数:35  
标签:process 中间件 request django 字符串 response

django中间件

内容概要

django中间件简介

django中间件两个重要方法

django自定义中间件

django中间件三个了解方法

基于django中间件实现功能的插拔式设计

内容详细

django默认有七个中间件 并且还支持用户自定义中间件

中间件主要可以用于:用户访问频率的校验 用户权限的校验等全局型功能需求

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',
]

image

自定义中间件

1.创建存储自定义中间件代码的py文件或目录(如果中间件很多)

2.产靠自带中间件的代码编写类并继承

3.在类中编写五个可以自定义的方法

4.一定要在配置文件注册中间件才可以生效

中间件可以定义五个方法,分别是:(主要的是process_request和process_response)

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)

需要掌握的两种方法

process_request

  1. 请求来的时候从上往下依次经过每一个注册了中间件里面的该方法 如果没有则直接跳过
  2. 如果该方法自己返回了HttpResponse对象那么不在往后执行而是直接原路返回

process_response

  1. 响应走的时候从下往上依次经过每一个注册了的中间件里面的方法 如果没有则直接跳过
  2. 该方法有两个request和response形参response指代的就是后端想要返回给前端浏览器的数据 该方法必须返回该形参 也可以替换
    如果在执行process_request方法的时候直接返回了HttpResponse对象那么会原路返回执行process_response不是执行所有

需要了解的

process_view

process_exception

process_template_response

自定义中间件实操

from django.utils.deprecation import MiddlewareMixin


class Mymiddle01(MiddlewareMixin):

    def process_request(self, request):
        print('from mymiddleware01 request')


    def process_response(self,request,response):
        return response


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

    def process_response(self,request,response):
        return response

image

process_request

image

process_response

image

如果在某一个中间件中直接返回了HTTP Response对象那么就不会在向下执行直接从当前中间件向上原路返回

image

那么也可以达成狸猫换太子的效果

image

结合生命周期流程图

image

image

django中间件的三个了解的方法

1.process_view

路由匹配成功之后执行的视图函数/类之前自动触发(顺序同process_request)

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse


class Mymiddle01(MiddlewareMixin):

    def process_request(self, request):
        print('from mymiddleware01 request')

    def process_response(self, request, response):
        print('from mymiddleware01 response')
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print('from mymiddleware01 view')

image

2.process_exception

视图函数/视图类执行报错自定触发(顺序同process_response)

def process_exception(self,request,exception):
    print('from mymiddleware01 exception')

image

3.process_template_response

视图函数/视图类返回的HttpResponse对象含有redner并且对应一个方法的时候自动触发(顺序同process_response)

一定要把接收的HttpResponse对象返回出去

def process_template_response(self,request,response):
    print('from mymiddleware01 template_response')
    return response

image

基于django中间件实现的插拔式设计

将各个功能制作成配置文件的字符串形式

如果想拥有该功能就编写对应的字符串

如果不想拥有则注释掉对应的字符串

补充知识

如果想用字符串导入模块

import importlib
s1 = 'bbb.b'  # aaa.bbb.ccc.b
res = importlib.import_module(s1)  # from aaa.bbb.ccc import b
print(res)  # <module 'bbb.b' from 'D:\\pythonProject03\\djangomiddle\\bbb\\b.py'>

注意字符串的结尾最小单位只能是py文件 不能是py文件里面的变量名

Django的settings文件里好多都是字符串 但是呢都是不简单的字符串

每一个字符串对应着一个py文件就代表着一个特定的功能

如果你想这个字符串有这个功能就加上 不想用就直接注释点

那么如何利用字符串导模块?

在纯python情况下

image

利用字符串导模块 内置模块importlib

image

如图:

image

按照点号从右开始切割一个 它的底层还是按照from导模块的句式

image

局限性这个模块的最小单位是py文件名 不能到py文件里的变量名

image

需求分析:

模拟编写一个消息通知功能(微信、qq、邮箱)

通过点击一个按钮就能触发消息

方式1:简单版 基于函数封装

def send_qq(content):
    print('从qq发送消息:'+str(content))

def send_weichat(content):
    print('从微信发送消息:'+str(content))

def send_email(content):
    print('从email发送消息:'+str(content))

def run():
    content = '我是阳过'
    send_qq(content)
    send_weichat(content)
    send_email(content)



if __name__ == '__main__':
    run()

image

方式2:基于django中间功能设计

NOTICES = [

    'qq.send_qq.QQ',
    'weichat.send_weichat.WeiChat',
    'myemail.send_email.Email',  # 包名不要与内置模块冲突

]

import os
import sys

BASE_DIR = os.path.dirname(__file__)
print(BASE_DIR)
sys.path.append(BASE_DIR)

import importlib


def send_message(content):
    for data in NOTICES:
        module, class_name = data.rsplit('.', maxsplit=1)  # 切割字符串
        print(module)
        module_obj = importlib.import_module(module)  # 以字符串的形式导入模块拿到对象

        obj = getattr(module_obj, class_name)()  # 反射拿到类对象加括号产生对象
        obj.send_message(content)  # 执行类中的send_message方法

基于Django中间件 模拟Django中间件差不多的形式表现的

image

但最有一个拿到的都是类名 可importlib模块的最小单位都是py文件名 这怎么搞呢?

start启动文件里面要用到notify包下所有的消息通知组件

那么导notify导的就是包里面的双下init.py

image

都添加到双下init.py中统一资源管理

导入配置文件settings.py 从右开始切割一次拿到就是字符串的py名文件路径 以及字符串的类名

image

再到启动文件中 如图:

image

那么怎样利用字符串去对象里拿一个名字呢?

想字符串、对象 >>> 想到就有反射:根据字符串获取对象对应的属性名(值)或方法名(函数体代码)

image

拿到类名加括号产生对象

对象点发送消息的方法

image

如图:

image

就实现跟Django中间件一样了 用你就写上 不用你注释掉

image

添加后注册

image

这样就实现了功能的插拔设计

总结:

利用到了内置模块importlib通过字符串导入模块、

以及rsplit从右开始max最大切割一次、

及反射getattr将模块名看成是对象再通过反射回去到对应模块中的字符串所对应的名字、

以及面向对象中的多态性当在使用面向对象的代码时在编写功能业务差不的代码时把他们的方法定义成相同的名字比较方便合理

标签:process,中间件,request,django,字符串,response
From: https://www.cnblogs.com/clever-cat/p/17006409.html

相关文章

  • 基于DJango和Pybind11,实现网络后端调用OpenCV算法
    本Blog来源于实际项目,所采用框架组合中,OpenCV实现算法主体、pybind11完成OpenCV的Python封装、django提供Web应用服务,三者协同配合,共同实现“网络后端调用OpenCV算法,解决特......
  • Django:auth认证模块
    目录一、django的auth认证模块1.什么是auth模块2.生成auth物理表二、创建django-admin账户1.创建超级管理员2.注册超级管理员账户3.登录admin账户三、auth模块中的方法1.导......
  • django中间件
    django中间件django默认有七个中间件并且还支持用户自定义中间件中间件主要可以用于:网站访问频率的校验用户权限的校验等全局类型的功能需求MIDDLEWARE=['......
  • Django之forms组件内容,Django中间件
    目录Django之forms组件内容,Django中间件今日内容概要今日内容详细forms组件渲染标签forms组件展示信息forms组件校验补充forms组件参数补充forms组件源码剖析modelform组件......
  • django forms组件,model from组件
    djangoforms组件,modelfrom组件内容概要forms组件简单使用form组件渲染标签forms组件校验补充forms组件参数补充forms组件源码剖析modelfrom组件forms组件小需求......
  • django,多对多,序列化组件,ORM批量操作数据,自定义分页器
    django,多对多,序列化组件,ORM批量操作数据,自定义分页器多对多三种创建方式1.全自动classBook(models.Model):title=models.CharField(max_length=32)authors......
  • Django之SQL注入漏洞复现(CVE-2021-35042)
    前言SQL注入的原理是对web请求,表单或域名等提交查询的字符串没有进行安全检测过滤,攻击者可以拼接执行恶意SQL命令,导致用户数据泄露漏洞原理Django组件存在SQL注入漏......
  • Django-auth认证模块
    1.auth认证模块1.django自带一个admin路由,但是需要我们自己填写管理员账号和密码。如果想要是用django的admin后台管理,首先需要创建表(直接执行数据库迁移命令会默认产......
  • django中的字段、字段参数、orm操作、QuerySet相关方法:
    常用字段 AutoField自增的整形字段,必填参数primary_key=True,则成为数据库的主键。无该字段时,django自动创建。一个model不能有两个AutoField字段。IntegerField一个整数类......
  • 使用unittest和Django搭配写一个接口测试平台
    一、项目需求:每个测试项目下面有多个测试用例1.对测试项目的.增.删.改.查,查看该测试项目下面所有的测试用例.为该测试项目批量导入,添加测试用例2.对项目下的接口进行......