中间件

django处理一个Request的过程是首先通过django 中间件,然后再通过默认的URL方式进行的。所以说我们要做的就是在django 中间件这个地方把所有Request拦截住,用我们自己的方式完成处理以后直接返回Response,那么我们可以简化原来的设计思路,把中间件不能处理的 Request统统不管,丢给Django去处理

中间件的安装

直接在django配置里面添加如下配置,Django本来就配置类好多中间件,中间件的执行顺序从上到下依次进行

MIDDLEWARE = [
'md.middleware.M1',  # 自定义的中间件
'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',
]

自定义中间件

其实每一个中间件都是一个类,类里面的方法django已经帮我们规定好了

from django.utils.deprecation import MiddlewareMixin


class M1(MiddlewareMixin):
    # 方法和参数必须要按照人家的规定的写
    def process_request(self, request):
        print('process_request')  # 注意,request没有返回值

    def process_response(self, response):
        print('process_response')
        return response

这样,django运行起来之后会先打印process_request,然后执行视图函数,视图函数执行完毕之后最后执行M1里面的process_response方法,也就是打印process_response

注意:如果新版本的django不能导入中间件的话,完全可以自己写模块

class MiddlewareMixin(object):
    def __init__(self, get_response=None):
        self.get_response = get_response
        super(MiddlewareMixin, self).__init__()

    def __call__(self, request):
        response = None
        if hasattr(self, 'process_request'):
            response = self.process_request(request)
        if not response:
            response = self.get_response(request)
        if hasattr(self, 'process_response'):
            response = self.process_response(request, response)
        return response

将这段代码放到自己定义的中间键前面就可以了

中间件和装饰器的区别

中间件是针对所有的请求和返回,而装饰器只是针对某个函数的,装饰器的粒度更小一些

中间件的方法

Django的中间件就是一个类,类里面有五个方法

  • process_request 请求刚进来执行的方法,
  • process_response 请求回去的时候执行的方法,必须要有返回值
  • process_view 路由匹配,等最后一个request执行完毕后会跳到第一个路由匹配进行执行
  • process_exception 程序报错执行所有中间件的exception方法,从最后一个开始一直执行到第一个然后再返回到最后一个response执行
  • process_tempalte_response

方法返回值

  • process_request 此方法不能有返回值,如果有返回值会直接执行与他平行的response,下面的不会执行 ,但是也可以对请求值进行判断,然后相应的复合条件的返回,不符合条件的不返回,也可以return None,和没有返回值是一个效果

  • process_response 必须要有返回值,因为他就是请求返回的时候执行的,没有返回值一定会报错,但是我们可以对返回值进行一定的修改

  • process_view 如果有返回值,会跳到最后一个response返回

  • process_exception 如果某个中间件捕捉到错误且返回值的话,直接跳到最后一个response执行

应用场景

由于中间件的特性,他的应用很广也很灵活

用户验证

class M1(MiddlewareMixin):
    if request.path_info == '/login/':
            return None
    # 方法和参数必须要按照人家的规定的写
    def process_request(self, request):
        if not request.session.get('user_info'):
            return redirect('/login/')

    def process_response(self, response):
        print('process_response')
        return response

注意:

  1. 这个方法用到了session,session也是一个中间件,因此我们在安装这个中间件的时候必须要放在session中间件的下面,最好放在最下面

    MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware', # session中间件
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'md.middleware.M1', # 放在session中间件下面
    ]

  2. 注意前面对request.path_info的判断,如果不加这个判断的话,跳转login页面的时候又会进行一次判断session,如果不符合继续跳转,就会形成死循环,加这个判断的一次是,如果判断当前路径为login的话返回None,也就是继续执行。

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

推荐阅读更多精彩内容