什么是Django中间件

中间件是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。
每个中间件组件负责做一些特定的功能。

自定义一个Django中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse
from django.core.cache import cache
import time
import random

class HelloMiddle(MiddlewareMixin):

def process_request(self, request):
print(request.META.get("REMOTE_ADDR"))
ip = request.META.get("REMOTE_ADDR")

# 针对某一路径进行数据处理
if request.path == "/app/getphone/":
if ip == "127.0.0.1":
if random.randrange(100) > 20:
return HttpResponse("恭喜你免费获取小米8 256G版本")

# 一分钟内只能请求10次,黑名单
black_list = cache.get('black', [])

if ip in black_list:
return HttpResponse('黑名单用户,凉凉')

requests = cache.get(ip, [])
while requests and time.time() - requests[-1] > 60:
requests.pop()

requests.insert(0, time.time())
cache.set(ip, requests, timeout=60)

if len(requests) > 20:
black_list.append(ip)
cache.set('black', black_list, timeout=60*60*24)
return HttpResponse('小爬虫小黑屋里待着吧')
if len(requests) > 9:
return HttpResponse('请求次数过于频繁, 小爬虫回家睡觉吧')
  1. 在工程目录下创建middleware目录
  2. 目录中创建一个python文件
  3. 在python文件中导入中间件的基类 from django.utils.deprecation import MiddlewareMixin
  4. 在类中根据功能需求,创建切入需求类,重写切入点方法
    1
    2
    3
    class LearnAOP(MiddlewareMixin):
    def process_request(self, request):
    print(‘request的路径’,request,GET.path)
  5. 启动中间件,在settings中进行配置,MIDDLEWARE中添加middleware.文件名.类名
    1
    2
    3
    MIDDLEWARE = [
    'middleware.LearnMiddle.HelloMiddle',
    ]

中间件顺序与分层

在请求阶段,在调用视图之前,Django 按照定义的顺序应用中间件 `MIDDLEWARE`,自顶向下。

如果其中一层决定停止并返回响应而不调用get_response,那么该层(包括视图)中的洋葱层都不会看到请求或响应。
响应将只通过请求传入的相同层返回。

中间件钩子

process_request

  • process_request(request)
  • process_request 方法的返回值可以是 None 也可以是 HttpResponse 对象
    • 返回值是 None 的话,按正常流程继续走,交给下一个中间件处理
    • 返回值是 HttpResponse 对象,Django 将不执行后续视图函数之前执行的方法以及视图函数,直接以该中间件为起点,倒序执行中间件,且执行的是视图函数之后执行的方法

process_view

  • process_view(request, view_func, view_args, view_kwargs)
    • request 是 HttpRequest 对象。
    • view_func 是 Django 即将使用的视图函数。
    • view_args 是将传递给视图的位置参数的列表。
    • view_kwargs 是将传递给视图的关键字参数的字典。
  • 返回值可以是 None、view_func(request) 或 HttpResponse 对象。

process_template_response

  • process_template_response(request, response)
  • request 是一个 HttpRequest 对象。response 是 TemplateResponse 对象(或者等效对象),它通过 Django 视图或中间件返回
  • process_template_response() 在视图被完全执行后调用,如果响应实例有 render() 方法,表明它是一个 TemplateResponse 或等效对象

process_response

  • process_response(request, response)
  • 该方法必须要有返回值,且必须是response

process_exception

  • process_exception(request, exception)
    • request 是 HttpRequest 对象。
    • exception 是视图函数异常产生的 Exception 对象。
  • 当视图引发异常时,Django 会调用 process_exception()

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request 方法。", id(request)) #在视图之前执行

def process_response(self,request, response): :#基于请求响应
print("md1 process_response 方法!", id(request)) #在视图之后
return response

def process_view(self,request, view_func, view_args, view_kwargs):
print("md1 process_view 方法!") #在视图之前执行 顺序执行
#return view_func(request)


def process_exception(self, request, exception):#引发错误 才会触发这个方法
print("md1 process_exception 方法!")
# return HttpResponse(exception) #返回错误信息

中间件常用功能

  • 实现统计功能
    • 统计IP
    • 统计浏览器
  • 实现权重控制
    • 黑名单
    • 白名单
  • 权限设置
  • 实现反爬虫
    • 反爬虫
      • 十秒之内只能搜索一次
    • 实现频率控制
  • 界面友好化
  • 应用交互友好化