django的中间件

我们首先来看一下django的settings.py中已经写好的中间件

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',
]


# SessionMiddleware代码
class SessionMiddleware(MiddlewareMixin):
    def __init__(self, get_response=None):
        self.get_response = get_response
        engine = import_module(settings.SESSION_ENGINE)
        self.SessionStore = engine.SessionStore

    def process_request(self, request):
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
        request.session = self.SessionStore(session_key)

    def process_response(self, request, response):
        """
        If request.session was modified, or if the configuration is to save the
        session every time, save the changes and set a session cookie or delete
        the session cookie if the session has been emptied.
        """
        return response.

# CsrfViewMiddleware代码
class CsrfViewMiddleware(MiddlewareMixin):
    def process_request(self, request):
        csrf_token = self._get_token(request)
        if csrf_token is not None:
            # Use same token next time.
            request.META['CSRF_COOKIE'] = csrf_token

    def process_view(self, request, callback, callback_args, callback_kwargs):
        ...
        return self._accept(request)

    def process_response(self, request, response):
        ...
        return response

# AuthenticationMiddleware代码
class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        assert hasattr(request, 'session'), (
            "The Django authentication middleware requires session middleware "
            "to be installed. Edit your MIDDLEWARE%s setting to insert "
            "'django.contrib.sessions.middleware.SessionMiddleware' before "
            "'django.contrib.auth.middleware.AuthenticationMiddleware'."
        ) % ("_CLASSES" if settings.MIDDLEWARE is None else "")
        request.user = SimpleLazyObject(lambda: get_user(request))


# 我们看到每个中间件基本上都是有process_request和process_response方法,如果没有就直接跳过,
# 'django.contrib.sessions.middleware.SessionMiddleware',其实就是这个中间件的路径,需要查看源码只需要from django.contrib.sessions.middleware import SessionMiddleware就可以了。

# 注意:
'''
    process_response一般传入两个参数,request和response
    return response
'''

# 下面我们来讲讲自定义中间件该怎么写

django支持程序员自定义中间件并且暴露五个可以自定义的方法

# 掌握
process_request
process_response
# 了解
process_view
process_exception
process_template_response

如何定义中间件

1.在项目名或者应用名下创建任意一个文件夹
2.在文件夹中创建一个任意名的py文件
3.在py文件中书写类(这个类必须继承MiddlewareMixin)
    然后在类里面可以自定义五个方法
4.需要将类的路径以字符串形式注册到配置文件中才能生效

创建自定义中间件

# 在apps下新建文件custom_middleware,在文件夹下新建文件my_middleware.py
from django.utils.deprecation import MiddlewareMixin
class My_middleware1(MiddlewareMixin):
    def process_request(self, request):
        print('我是自定义的第一个process_request中间件')
    def process_response(self,request, response):
        print('我是自定义的第一个process_response中间件')
        return response

class My_middleware2(MiddlewareMixin):
    def process_request(self,request):
        print('我是自定义的第二个process_request中间件')
    def process_response(self,request, response):
        print('我是自定义的第二个process_response中间件')
        return response

# 写完一定要记得在settings.py的MIDDLEWARE = [...]中写入路径,以字符串的形式
MIDDLEWARE = [
                 'apps.custom_middleware.my_middleware.My_middleware1',
                    'apps.custom_middleware.my_middleware.My_middleware2',
             ]

# view.py中直接一个get请求打印并返回一个数据
from django.shortcuts import HttpResponse

def index(request,*args,**kwargs):
    print('我是视图函数')
    return HttpResponse('我是视图函数')


# 执行django,控制台得到打印结果
'''
    [21/Apr/2021 16:39:04] "GET /index/ HTTP/1.1" 200 18
    我是自定义的第一个process_request中间件
    我是自定义的第二个process_request中间件
    我是视图函数
    我是自定义的第二个process_response中间件
    我是自定义的第一个process_response中间件
    Process finished with exit code 0
'''

# 我们可以看出process_request是请求来的时候执行,从上往下依次执行,而process_response则是从下向上依次执行。还有主要process_response结尾的时候返回了一个response,而process_request并没有return。

# 假入在第一个process_request里返回return会怎么样呢
# 直接返回return None结果还是和上面一样,我们返回点数据试试,其他不变,只加一个return
    def process_request(self, request):
        print('我是自定义的第一个process_request中间件')
        return HttpResponse('hello')



# 执行django,控制台得到打印结果
# 浏览器页面显示hello
'''
我是自定义的第一个process_request中间件
我是自定义的第一个process_response中间件
[21/Apr/2021 16:50:09] "GET /index/ HTTP/1.1" 200 5
'''
# 说明process_request直接返回数据,那么django就直接执行和process_request同级别的process_response,然后返回数据,不会在往下执行了。

# 下面试试process_response,return返回数据

# 假如在第一个process_response里返回return会怎么样呢
# 直接返回return None结果还是和上面一样,我们返回点数据试试,其他不变,只加一个return
    def process_response(self,request, response):
        print('我是自定义的第一个process_response中间件')
        return HttpResponse('hello')


# 执行django,控制台得到打印结果
# 浏览器页面显示hello
'''
[21/Apr/2021 16:54:04] "GET /index/ HTTP/1.1" 200 5
我是自定义的第一个process_request中间件
我是自定义的第二个process_request中间件
我是视图函数
我是自定义的第二个process_response中间件
我是自定义的第一个process_response中间件
'''
# 我们可以看出来,浏览器显示的数据是process_response里面打印的数据,但是控制台打印的是视图函数的数据

下面是了解知识点

# process_view
# 路由匹配成功之后,视图函数执行之前,会自动执行中间件里面的该方法,从上往下。
def process_view(self,request,view_name,*args,**kwargs)
    print('...')


# process_exception
# 返回的Http对象由render属性的时候才会触发,从下往上执行。
def process_exception()
    print('...')


# process_template_response
# 当视图函数中出现异常的情况下触发,从下往上
def process_template_response(self,request,response):
    print('...')
    return response
# view.py
def index(request):
    obj=HttpResponse('index')
    def render():
        print('...')
        return HttpResponse('执行process_template_response方法')
    obj.render = render
    return obj
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务