笔记: Django Rest Framework 访问频率

首先自定义一个访问频率的类,然后在试图中引用就可以了,如下:

1, 先定义访问频率的类,如下代码:没有继承restframework的任何类

# 下面是访问频率的代码,没有继承
# 这个代码根据访问的IP地址 来进行访问限制。。。。同理可作根据访问的用户名来进行访问限制。

#这里定义一个字典,用来记录访问频率, 这个字典的key就是ip地址,value就是访问的时间记录值是一个value,这个可以在这里用一个字典,也可以翻到缓存,也可以翻到数据库
VISIT_RECORD = {}

import time
from rest_framework.throttling import BaseThrottle
class VisitThrottle(object):
    def __init__(self):
        self.history = None
    # 60秒内只能访问3次
    def allow_request(self, request, view):
        #return True 表示可以继续访问
        #return False 表示访问频率太高,被限制了

        #1, 获取用户的ip地址
        remote_addr = request.META.get ('REMOTE_ADDR')

        #判断ip在不在VISIT_RECORD里面,然后添加时间
        ctime = time.time()
        #下面的if语句是第一次访问的设置
        if remote_addr not in VISIT_RECORD:
            VISIT_RECORD[remote_addr] = [ctime,]
            return True
        history = VISIT_RECORD.get(remote_addr) #定义history历史记录,这里获取指定ip地址的访问列表
        self.history = history #把这个赋值给整个类的变量,然后就可以给下面的wait()函数使用了
        #下面定义一个循环,用来吧当前时间和history里面的时间进行比较,因为考虑用到列表的POP操作,所以这里我们把时间从前面插入,最近的时间在左边,最远的时间在右边
        while history and history[-1] < ctime-60: #因为是一分钟中之内,所以是减60
            history.pop() #如果最右边的时间小于当前时间减去60,那么执行pop操作,吧最右边的时间清空,这里可以循环比较,直到列表被清空。

        #下面开始对访问的history的个数进行限制,如果小于3我们返回True ,表示可以继续访问
        if len(history) < 3:
            history.insert(0, ctime)#吧当前时间插入到第0个位置
            return True


    def wait(self):
        # return 返回值,返回几,在页面会提示还剩多少秒可以继续访问,比如我们写 return 10 表示还剩10s可以继续访问
        # 可以自定义动态的时间,然后返回,然后就会动态提示还剩多少秒返回
        ctime = time.time()
        left_time = 60-(ctime-self.history[-1])
        return left_time

2, 在试图中是用:

class AuthView(APIView):
    '''
    用于用户登陆
    这里拿到前台发过来的用户名和密码,然后去数据库校验,同时我们还生成了token,然后还给用户返回了token,用于用户后面发送请求,必须要
    带上这个token的请求.
    '''
    # authentication_classes = [] #这里因为在全局中设置了验证类,所以在这里要把这个列表为空,好让这个视图可以不经过全局的验证,直接执行.

    #访问频率的类列表设置
    throttle_classes = [VisitThrottle,]


    def get(self, request, *args, **kwargs):
        return HttpResponse('hello workd')

    def post(self, request, *args, **kwargs):
        ret = {'code':1000, 'msg':None}
        try:
            user = request._request.POST.get('username')
            password = request._request.POST.get('password')
            obj = models.UserInfo.objects.filter(username=user, password=password).first()
            if not obj:
                ret['code'] = 1001
                ret['msg'] = '用户名或者密码错误'
            #未登陆用户创建token,采用上面定义的md5()函数来生成token
            token = md5(user)
            #保存金数据库,有就更新,没有就创建,因为是只能用最新的token,所以需要更新操作.
            models.UserToken.objects.update_or_create(user=obj, defaults={'token':token})
            #需要给用户返回token
            ret['token'] = token
        except Exception as e:
            ret['code']=1002
            ret['msg']='请求异常'


        return JsonResponse(ret)

3, 也可以在全局中配置


REST_FRAMEWORK = {
    # 'DEFAULT_AUTHENTICATION_CLASSES':['api.utils.auth.FirstAuthenticate',],  #注意这个格式, 这里的DEFAULT_AUTHENTICATION_CLASSES是restframework 配置规定的, 后面的列表就是认证的类. 里面写的是认证类的路径
    #下面两句是匿名用户的设置:
    'UNAUTHENTICATED_USER':None, #匿名, 则request.user = None
    'UNAUTHENTICATED_TOKEN':None, #匿名, 则request.token = None
    # 'DEFAULT_PERMISSION_CLASSES':['api.utils.permission.MyPermission'],
    'DEFAULT_THROTTLE_CLASSES': ['api.utils.throttle.MyThrottle']
}

定义继承自SimpleRateThrottle()类

1, 这个类中的设置
笔记: Django Rest Framework 访问频率_第1张图片
笔记: Django Rest Framework 访问频率_第2张图片2, views.py 文件中的代码,继承的代码,如下:

# 下面是继承自SimpleRateThrottle类的实现,他这个类,已经帮我们实现好了基于IP的访问频率控制,只需要继承之后设置一些参数就可以了
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
class VisitThrottle1(SimpleRateThrottle):
    # scope = 'lxbai' #这个是自定义的,这个scope 用来设置访问频率的key的,这个设置了之后,就需要在settings.py中定义了,如果这里不写scope,只写下面的rate也是不错的,就是专门用来控制这个类的。
    rate = '10/m' #这个参考源码,设置60秒10次。

    #重写需要重写的函数
    #把cache_key设置成id,就是把这个ip地址设置成key,然后history设置成value
    def get_cache_key(self, request, view):
        return self.get_ident(request)

解释1: 如果在这里设置scope了之后,就不用在这里设置rate了,就需要在settings.py中定义,如下:

REST_FRAMEWORK = {

    'DEFAULT_THROTTLE_RATES':{
        'lxbai': '10/m' #这个scope   lxbai是我们在那个继承类中定义好的。
    }

}

解释2:如果在这个不设置scope, 就用那个rate设置成rate='10/m’就可以了,也是一分钟访问10次。

总结: 这个部分有很多的设置,做的时候,参考原视频和源码。

你可能感兴趣的:(django)