Django中间件

Django中间件

HTTP请求周期初识

在HTTP请求周期中,之前的了解是:用户请求->URL->view视图->url->用户

实际在用户请求和URL之间是中间件

Django 的中间件的本质是类,有几个中间件,就有经过几个类,每个类都有相应的方法。

Django中的中间件

Django的中间件在setting中MIDDLEWARE

中间件是有顺序的,按照setting中的从上到下顺序执行

Django1.10以上的版本中,当请求从上到下执行,如到达csrf出现问题,会从同一级别的csrf返回。

在之前的版本中,请求到达csrf出现问题,会从最后一个中间件返回。

自定义中间件

可以在当前的中间件的基础上进行修改,也可以自己定制新的中间件

小功能:

  • 比如,黑名单功能,请求来的时候判断用户的IP是否在黑名单中,如果在,禁止请求

  • 在中间件中添加装饰器判断用户是否登录

自定义中间件:

  • 继承MiddlewareMixin
  • process_request 可以没有返回值,有返回值的时候直接从同级别的位置返回
  • process_response 有三个参数,必须有返回值

中间件

from django.utils.deprecation import MiddlewareMixin


class M1(MiddlewareMixin):
    def process_request(self, request):
        print("m1.request")

    def process_response(self, request, response):  # 还有一个response参数
        print("m1.response")
        return response

视图

from django.shortcuts import render,redirect,HttpResponse

def test(rquest):
    print('test')
    return HttpResponse("ok")

结果:

m1.request
test   视图函数的执行
m1.response

process_request有返回值的情况

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,redirect,HttpResponse

class M1(MiddlewareMixin):
    def process_request(self, request):
        print("m1.request")
        return HttpResponse('okokoko') # 这里添加了返回值

    def process_response(self, request, response):  # 还有一个response参数
        print("m1.response")
        return response

结果:没有执行视图函数

m1.request
m1.response  直接从自己的方法返回

注册中间件

按顺序执行

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',
    # 'md.M1',
    # 'md.M2',
    'm1.M1',  # 自己的中间件 文件名+类名

]

深入HTTP请求周期

首选要明白的是web框架的本质是socket,但是Django是没有的,默认的wsgiref,生产环境用的是uwsgi

WSGI(Web Server Gateway Interface)Web服务网关接口已经成为了一种规范

wsgi是Django开始的地方

自定义中间件view

下面的情况是执行完m1的request后执行m2的request.

执行view的时候重新返回m1的view,然后是m2的view

中间执行view视图函数

最后执行m2的response,m1的response

from django.utils.deprecation import MiddlewareMixin


class M1(MiddlewareMixin):
    def process_request(self, request):
        print("m1.process_request")

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("m1.process_view")


    def process_response(self, request, response):
        print("m1.process_response")
        return response  # response必须要有返回值


class M2(MiddlewareMixin):
    def process_request(self, request):
        print('m2.process_request')

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("m2.process_view")

    def process_response(self, request, response):
        print('m2.process_response')
        return response  #

结果:

m1.process_request
m2.process_request
m1.process_view
m2.process_view
test
m2.process_response
m1.process_response

*在view中是用callback方法

通过callback找到了视图函数的名字,callback加括号就是执行视图函数一次

注意的是m1的process_view没有返回值的时候是执行一次view中的test函数

有返回值的时候m2的process_view不会执行

from django.utils.deprecation import MiddlewareMixin


class M1(MiddlewareMixin):
    def process_request(self, request):
        print("m1.process_request")

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("m1.process_view")
        response = callback(request, *callback_args, **callback_kwargs)
        # 这里是找函数 url对应的函数名
        # return response   有response的时 从这里返回  

    def process_response(self, request, response):
        print("m1.process_response")
        return response  # response必须要有返回值


class M2(MiddlewareMixin):
    def process_request(self, request):
        print('m2.process_request')

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("m2.process_view")

    def process_response(self, request, response):
        print('m2.process_response')
        return response  #

结果:

m1.process_request
m2.process_request
m1.process_view
test   # 这是callback执行的
m2.process_view
test
m2.process_response
m1.process_response

process的方法

  • process_request
  • process_response 一定要有返回值
  • process_view
  • process_exception(错误异常)
  • process_template
    • 视图函数中有render方法才执行
    • 自己写类进行封装
      返回对象有render方法
process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)

中间件应用

对所有请求或一部分请求做批量处理

例如把所有的请求筛选,缓存中有,直接从缓存中拿

posted @ 2017-07-03 20:11  hzxPeter  阅读(219)  评论(0编辑  收藏  举报