day85

频率校验

源码分析

声明:基于rest_framework的频率校验

  1.首先我们进入到APIView下的dispatch,因为由此方法开始分发的

    2.可以看到dispatch方法下有一个initial的方法,进入该方法

  3.由此进入频率控制

  4.进入check_throttles方法,我们发现他最终是调用了该方法,所以我们需要在自定义时,写上这个方法

  5.同时我们进入上张图中的迭代对象,发现与认证组件和权限控制一样他也需要在视图类中写一个列表

  6.最后我们想他若是频率控制住后需要返回信息来到BaseThrottle,发现可以重写wait返回一个数字。

 

代码实现

 自定义频率控制

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
import time

class MyThrottle(BaseThrottle):
    dic = {'ip': []}

    def __init__(self):
        now_time = 0
        history = []

    def allow_request(self, request, view):
        self.now_time = time.time()
        ip = request.META.get("REMOTE_ADDR")
        if ip not in self.dic:
            self.dic[ip] = [self.now_time, ]
            return True
        self.history = self.dic.get(ip)
        while self.history and self.now_time - self.history[-1] > 60:
            self.history.pop()

        if len(self.history) < 3:
            self.history.insert(0, self.now_time)
            return True
        return False

    def wait(self):
        return 60 - (self.now_time - self.history[-1])
View Code

 视图函数

from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from app01 import the
from rest_framework import exceptions



class User(APIView):
    throttle_classes = [the.MyThrottle, ]

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')
View Code

 

使用rest_framework自带的频率控制

settting中设置

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'ttt': '3/m'
    }
}

在试图类中写一个继承Throttled的类可以控制返回信息为中文

    def throttled(self, request, wait):
        class Mythrottled(exceptions.Throttled):
            default_detail = '访问次数过多'
            extra_detail_singular = '剩余 {wait} 秒后访问.'
            extra_detail_plural = '剩余 {wait} 秒后访问.'

        raise Mythrottled(wait)

在py文件中设置相关值

class MyThrottle(SimpleRateThrottle):
    scope = 'ttt'

    def get_cache_key(self, request, view):
        # self.get_ident( request)
        return request.META.get('REMOTE_ADDR')

局部控制

局部使用:
	-在视图类中写
	    throttle_classes = [MyThrottle,]

全局控制

全局使用:
	-在setting中写
	    'DEFAULT_THROTTLE_CLASSES':['app01.MyAuth.MyThrottle',],
    -局部禁用:
	-在视图类中写
	    throttle_classes = []

  

posted @ 2018-12-14 19:18  yyxxff  阅读(170)  评论(0编辑  收藏  举报