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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

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