django.core.exceptions.ImproperlyConfigured: No default throttle rate set for ‘xxx‘ scope频率配置报错

djangorestframework=3.12.2  版本

一、settings.py中配置频率限制

settings.py中配置:

#频率限制 :全局配置
REST_FRAMEWORK={
    'DEFAULT_THROTTLE_CLASSES':(
    ' util.throttling.IPThrottle', #全局默认使用IP的限制
    ),
     'DEFAULT_THROTTLE_RATES':{
        'IP':'3/m', #一个ip一分钟只能访问3次
        'name':'1/m', #请求携带的数据进行频率限制,1分钟1次
    }
}

在util/throttling.py下写频率限制类

from rest_framework.throttling import SimpleRateThrottle

class IPThrottle(SimpleRateThrottle):
    # 在settings中配置频率时使用到的关键字,有scope来指定
    scope = 'IP'

    def get_cache_key(self, request, view):
        # 这里return什么,就以什么作为限制,这里限制ip,直接return ip就可以
        print(request.META.get('REMOTE_ADDR'))
        return request.META.get('REMOTE_ADDR')

class NameThrottle(SimpleRateThrottle):
    #在settings中配置好
    scope = 'name'
    def get_cache_key(self, request, view):
        #根据请求携带的name数据进行限制
        if request.method=='GET':
            return request.query_params.get('name')
        else:
            return request.data.get('name')

视图:

from rest_framework.views import APIView
from rest_framework.response import Response
from util.throttling import NameThrottle
class NameAPIView(APIView):
    throttle_classes = [NameThrottle,]
    scope = 'name'
    def get(self,requst):
        str_time = time.strftime('%Y-%m-%d %H:%M:%S')
        return Response({'scope': "NAME", 'time': str_time})

报错信息:

File "C:\Virtualenvs\python36_cms\lib\site-packages\rest_framework\throttling.py", line 95, in get_rate
    raise ImproperlyConfigured(msg)
django.core.exceptions.ImproperlyConfigured: No default throttle rate set for 'name' scope

报错信息解析:意思是没有配置scope =’name‘对应的频率限制,但是我在settings.py中的频率配置中,配置了 'name':'1/m', 在写NameThrottle 频率类也定义scope='name',就很诡异

二、为了不修改drf版本且还能使用频率限制功能

根据报错,找到源码,发现是SimpleRateThrottle类中的get_rate(self)方法报错,拿不到scope的限制频率。

解决方法:在自定义的频率限制类中重写get_rate() 方法

class NameThrottle(SimpleRateThrottle):
    #在settings中配置好
    scope = 'name'
    def get_cache_key(self, request, view):
        #根据请求携带的name数据进行限制
        if request.method=='GET':
            return request.query_params.get('name')
        else:
            return request.data.get('name')
    def get_rate(self):
        #把频率限制,不再写在settings.py中,直接由该函数返回即可
        return '5/m'

猜你喜欢

转载自blog.csdn.net/weixin_46371752/article/details/129562632