中间件

django中间件

中间件简介

django中间件类似于django的门户,所有的请求和响应走都必须经过中间件,django默认自带七个中间件,每一个中间件都有它自己的功能,除了它默认的之外,还支持自定义中间件,加多少个都可以

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

IDDLEWARE = [
    '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',
]

如何自定义中间件

1.创建存储自定义中间件代码的py文件或目录(如果中间件很多)
2.参考自带中间件的代码编写类并继承
3.在类中编写五个可以自定义的方法
	process_request
    process_response
    process_view(了解)
    process_template_response(了解)
    process_exception(了解)

1.定义中间件

image

2.配置中间件

image

  • process_request

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

    image

    image

  • process_response

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

    image

    image

  • process_view

    当路由匹配成功之后 执行视图函数之前 自动触发
    
    process_view(self, request, view_func, view_args, view_kwargs)
    该方法有四个参数
    request是HttpRequest对象
    view_func是Django即将使用的视图函数。(它是实际的函数对象,而不是函数的名称作为字符串)
    view_args是将传递给视图的位置参数的列表.
    view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。
    Django会在调用视图函数之前调用process_view方法。
    它应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,那么将不会执行Django的视图函数,而是直接在中间件中掉头,倒叙执行一个个process_response方法,最后返回给浏览器
    
  • process_excption

    当视图函数报错之后 自动触发
    
    process_exception(self, request, exception)
    该方法两个参数:
    一个HttpRequest对象
    一个exception是视图函数异常产生的Exception对象。
    这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行
    
  • process_template_response

    当视图函数返回的数据对象中含有render属性对应render函数才会触发
    
    process_template_response(self, request, response)
    它的参数,一个HttpRequest对象,response是TemplateResponse对象(由视图函数或者中间件产生)。
    process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)。
    
    

    image

    image

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

"""
模块的导入方法
	import 句式
	from ... import... 句式
"""
s1 = 'bbb.b'  # aaa.bbb.ccc.b
res = importlib.import_module(s1)
print(res)  # <module 'bbb.b' from 'D:\\pythonProject03\\djangomiddle\\bbb\\b.py'>
'''注意字符串的结尾最小单位只能是py文件,不能是py文件里面的变量名'''

image

简单得到函数式封装

def qq(content):
    print('来自qq的消息:%s', % content)
def wechat(content):
    print('来自微信的消息:%s', % content)
def email(content):
    print('来自邮箱的消息:%s', % content)
    
def send_all(content):
    # qq(sontent)  不想发哪个消息就注释哪个函数
    wechat(content)
    email(content)
    
if __name__ == 'main':
    send_all('元旦三天假 你想怎么过?')

配置文件插拔式设计

image

qq.py文件

class Qq(object):  # 为了兼容括号内写object
    def __init__(self):
        pass  # 模拟发送qq之前 应该准备的代码环境
    
    def send_msg(self, content):
        print('qq消息通知:', content)

__ init.py __文件

import importlib
from settings import NOTIFY_LIST

def send_all(content):
    for full_path in NOTIFY_LIST:  # path='notify.email.Email'
        module_path,class_str_name = i.rsplit('.', maxsplit=1)  # 'notify.email' 'Email'
        # 1.利用字符串导入模块 拿到模块名
        model_name = importlib.import_module(module_path)  # from notify import email
        # 2.利用反射从模块中获取字符串对应的类名
        class_name = getattr(module_name, class_str_name)  # Email
        # 3.利用类名加括号产生对象
        obj = class_name()
        # 4.对象调用发送消息的方法
        obj.send_msg(content)

setting.py文件

NOTIFY_LIST = [
    'notify.email.Email',
    'notify.qq.Qq',
    'notify.wechat.Wechat'
    # 'notify.msg.Msg'  # 如果哪天不想要了,可以直接注释掉
]

start.py文件

import notify

if __name__ == '__main__':
    notify.send_all('今天冬至哦!')
posted @ 2022-12-21 22:01  dear丹  阅读(34)  评论(0编辑  收藏  举报