Django中的中间件

Posted huiyichanmian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django中的中间件相关的知识,希望对你有一定的参考价值。

1、AOP (面向切面编程(钩子))

一个轻量级,底层的插件,可以介入Django的请求和响应过程(面向切面编程),本质上就是一个Python类

面向切面编程(Aspect Oriented Programming)简称AOP。AOP的主要实现目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合的隔离效果

在不修改原有代码的情况下,动态注入一部分代码,类似于装饰器函数

2、Django中内置的一个轻量级的切面接口

技术图片

(1)、process_request

process_request(self,request)

在执行视图函数前被调用

每个请求上都会调用,不主动进行返回或返回HttpResponse对象

(2)、process_views

process_view(self,request,view_func,view_args,view_kwargs)

调用视图函数之前执行

每个请求都会调用,不主动进行返回或返回HttpResponse对象

(3)、process_template_response

process_template_response(self,request,response)

在视图函数刚好执行完后进行调用

每个请求都会调用,不主动进行返回或返回HttpResponse对象

(4)、process_response

process_response(self,request,response)

所有响应返回浏览器之前调用

每个请求都会调用,不主动进行返回或返回HttpResponse对象

(5)、process_exception

process_exception(self, request, exception)

当视图函数抛出异常时调用,不主动进行返回huo返回HttpResponse对象

3、自定义中间件

(1)、创建一个文件夹(最好放在工程根目录下)

middleware

(2)、创建一个python文件

(3)、伪装成系统的中间件,继承自MiddlewareMixin

from django.utils.deprecation import MiddlewareMixin

(4)、注册中间件

在settings中进行配置,在 MIDDLEWARE中添加,

middleware.文件名.类名

(5)、重写切点,实现自己的功能

如果我们逻辑中没有返回值,那么程序执行的时候会按照原有逻辑执行

如果我们做出了返回,那么程序将会从切点处切开,直接回到浏览器

4、实现功能

(1)、限制访问次数(10秒访问一次)

import time
from django.core.cache import cache
from django.http import HttpResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin


class HelloMiddle(MiddlewareMixin):

    def process_request(self, request):
        ip = request.META.get("REMOTE_ADDR")
        result = cache.get(ip)
        if result:
            return HttpResponse("您的访问过于频繁,请10秒之后再次搜索")
        cache.set(ip, ip, timeout=10)

(2)、反爬(一分钟请求10次认定爬虫)

a、普通版本

import time
from django.core.cache import cache
from django.http import HttpResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin


class HelloMiddle(MiddlewareMixin):

    def process_request(self, request):
        ip = request.META.get("REMOTE_ADDR")
        black_list = cache.get(black,[])
        
        requests = cache.get(ip, [])
        while requests and time.time() - requests[-1] > 60:  # 如果requests存在,并且当前时间比列表中最后一个时间大60,则弹出最后一个。(最新的数据从头部插入)
            requests.pop()
        if len(requests) > 10: # 如果访问大于十次
            return HttpResponse(请求过于频繁)
        requests.insert(0,time.time())
        cahe.set(ip, request, timeout=60)

b、升级版本

import time
from django.core.cache import cache
from django.http import HttpResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin


class HelloMiddle(MiddlewareMixin):

    def process_request(self, request):
        ip = request.META.get("REMOTE_ADDR")
        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存在,并且当前时间比列表中最后一个时间大60,则弹出最后一个。(最新的数据从头部插入)
            requests.pop()
        requests.insert(0,time.time())
        cahe.set(ip, requests, timeout=60)
        if len(requests) > 30:
             black_list.append(ip)
             cache.set(black, black_list, timeout=60*60*24)
             return HttpResponse("小爬虫小黑屋里呆着吧")
        if len(requests) > 10: # 如果访问大于十次
            return HttpResponse(请求过于频繁)
                

5、执行顺序

中间件的配置顺序特别重要,请求按照中间件的配置顺序执行,响应按照中间件的倒序执行。

以上是关于Django中的中间件的主要内容,如果未能解决你的问题,请参考以下文章

无法更新 View Pager 中的中间片段。

django 1.5中的django.utils.thread_support

django-缓存的三种应用

Django高级——中间键

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段