Django中请求的生命周期和实现简单的黑名单过滤的中间件

1. 描述Django请求的生命周期

客户端通过http协议发送请求报文到web服务器, web服务器解析请求报文, 通过wsgi协议把解析好的请求发送到Django项目, Django项目产生request对象, 依次的从上到下调用中间件中的process_request方法, 进行url匹配, 依次从上到下调用中间件中的process_view方法, 调用视图, 依次从下到上的调用中间件中的process_response方法特别注意的是: 在依次调用中间件中的process_request, process_view, process_response方法时, 如果process_request方法中返回了响应对象, 那么后续的url匹配, process_view方法的调用以及视图的调用都不会走, 会直接的跳到process_response这个方法中执行, 同样的如果执行到中间件的process_view方法中返回了响应对象, 那么不会再去调用视图, 直接跳到process_response方法中执行, process_response返回响应通过wsgi协议给web服务器, web服务器构造响应报文, 再通过http协议发送响应报文到客户端
Django中请求的生命周期和实现简单的黑名单过滤的中间件_第1张图片

2. 自定义实现Django中的中间件(过滤黑名单)

django中自带的中间件, 比较熟悉的有CsrfViewMiddleware, 我们可以去看一下, 自带的中间件怎么实现的
from django.middleware.csrf import CsrfViewMiddleware

from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin


# 需求: 黑名单, 不允许访问任何视图函数

class BlackIpMiddleware:
    """黑名单过滤中间件"""
	# 测试添加本地为黑名单
    BLACK_IP = ['127.0.0.1']

    def __init__(self, get_response=None):
        """django 1.10之前, 服务器响应第一个请求时才会调用, 之后启动应用即调用"""
        print('__init__')
        self.get_response = get_response
        super().__init__()

    def __call__(self, request):
        """每个请求调用一次的__ call __()"""
        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

    def process_request(self, request):
        """在产生request对象, 进行url匹配之前调用"""
        print('process_request')

    def process_view(self, request, view_func, *args, **kwargs):
        """在url匹配后, 调用视图函数之前"""
        # 获取用户ip
        print('process_view')
        user_ip = request.META['REMOTE_ADDR']
        if user_ip in self.BLACK_IP:
            return HttpResponse('

Forbidden

'
) def process_response(self, request, response): """视图函数调用之后, 内容返回给浏览器之前""" print('process_response') return response def process_exception(self, request, exception): """视图函数出现异常, 会调用这个函数""" print(exception) print('exception') 过滤效果入下:

在这里插入图片描述

上面的代码我导入了一个扩展类, 上面的中间件类中的__init__()和__call__()在扩展类中都已经实现了, 可以直接继承这个扩展类, 直接编辑中间件中的方法即可

你可能感兴趣的:(Django中请求的生命周期和实现简单的黑名单过滤的中间件)