Django如何自定义中间件

一个完整的中间件设有5个钩子函数,Django将用户请求到网站的过程进行阶段划分,每个阶段对应执行某个钩子函数:

  • __ init __ ():初始化函数,运行Django将自动执行该函数
  • process_request():完成请求对象的创建,但用户访问的网址尚未与网站的路由地址匹配
  • process_view():完成用户访问的网址与路由地址的匹配,但尚未执行视图函数
  • process_exception():在执行视图函数的期间发生异常
  • process_response():完成视图函数的执行,但尚未将响应的内容返回浏览器

每个钩子函数都有固定的执行顺序,以MyDjango为例,在MyDjango文件夹中创建myMiddleware.py文件,该文件用于定义中间件。
在定义中间件之前,首要实现网站功能,分别在MyDjango的urls.py、index的urls.py、index的views.py和templates的index.html中编写以下代码:

# MyDjango的urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(('index.urls', 'index'), namespace='index'))
]

# index的urls.py
from django.urls import path
from .views import *

urlpatterns = [
    path('', index, name='index'),
]

# index的views.py
from django.shortcuts import render
from django.http import Http404


def index(request):
    if request.GET.get('id', ''):
        raise Http404
    return render(request, 'index.html', locals())
<!--templates的index.html-->
<!DOCTYPE html>
<html lang="zh-hans">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <div>Hello Django</div>
</body>
</html>

视图函数index设置了主动抛出404异常,用于验证钩子函数process_exception。

下一步在MyDjango的myMiddleware.py中定义中间件MyMiddleware:

from django.utils.deprecation import MiddlewareMixin


class MyMiddleware(MiddlewareMixin):
    def __init__(self, get_response=None):
        self.get_response = get_response
        print('this is __init__')

    def process_request(self, request):
        """生成请求对象后,路由匹配之前"""
        print('this is process_request')

    def process_view(self, request, func, args, kwargs):
        """路由匹配后,视图函数调用之前"""
        print("this is process_view")

    def process_exception(self,request,exception):
        """视图函数发生异常时"""
        print('this is process_exception')

    def process_response(self, request, response):
        """视图函数执行后,响应内容返回浏览器之前"""
        print('this is process_response')
        return response

运行MyDjango,项目将自动运行中间件MyMiddleware的初始化函数 __ init __ (),初始化函数必须设置函数参数get_response,还需要将参数get_response设为类属性self.get_response,否则在访问网站时将提示AttributeError异常。

当用户在浏览器上访问某个网址时,Django为当前用户创建请求对象,请求对象创建成功后,程序执行钩子函数process_request,通过重写该函数可以获取并判断用户的请求是否合法。函数参数request代表用户的请求对象,他与视图函数的参数request相同。

钩子函数process_request执行完成后,Django将用户访问的网址与路由信息进行匹配,在调用函数或视图类之前,程序将执行钩子函数process_view。函数参数request代表用户的请求对象;参数func代表视图函数或视图类的名称;参数args和kwargs是路由信息传递给视图函数或视图类的变量对象。

钩子函数process_view执行完毕后,Django将执行视图函数或视图类。如果在执行视图函数或视图类的过程中出现异常报错,程序就会执行钩子函数process_exception。函数参数request代表用户的请求对象,参数exception代表异常信息。

视图函数或视图类执行完成后,Django将执行钩子函数process_response,该函数可以对视图函数或视图类的响应内容进行处理。当钩子函数prrocess_response执行完成后,程序才把响应内容返回给浏览器生成网页信息。

最后我们在MyDjango的settings.py中添加自定义中间件MyMiddleware:

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',
    'MyDjango.myMiddleware.MyMiddleware'
]

在Pycharm中运行MyDjango,在浏览器上访问127.0.0.1:8000/?id=1,由于路由地址没有请求参数id,因此视图函数将主动抛出404异常,Django将触发process_exception函数。


image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 中间件 中间件介绍 什么是中间件 官方的说法是:中间件是一个用来处理Django的请求和相应的框架级别的钩子。他是...
    可笑的黑耀斑阅读 384评论 0 0
  • 目录 一、中间件简介 在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合...
    CaiGuangyin阅读 840评论 0 3
  • 中间件 什么是中间件 中间件就是一个用来全局的处理请求和响应的框架级别的钩子.它本质上是一个类.说的直白一点就是中...
    莫辜负自己的一世韶光阅读 506评论 0 1
  • 什么是中间件 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件...
    Pope_Li阅读 395评论 0 0
  • 中间件是 Django 用来处理请求和响应的钩子框架。它是一个轻量级的、底层级的“插件”系统,用于全局性地控制Dj...
    liujiangblog阅读 1,329评论 0 4