You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Rest Framework自定义限流类无法正常工作问题求助

解决Django REST Framework自定义限流不生效的问题

问题排查与修复步骤

1. 检查缓存服务是否正常运行

DRF的限流依赖缓存存储请求计数,若缓存未正常工作,限流规则完全不会生效。

  • 先确认memcached服务已启动:执行ps aux | grep memcached查看进程,若未启动则启动服务(如systemctl start memcached)。
  • 若暂时无法使用memcached,可临时切换到本地内存缓存测试:
    # settings.py
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        }
    }
    
  • 验证缓存可用性:在Django Shell中执行:
    from django.core.cache import cache
    cache.set('test_key', 'test_value', 60)
    print(cache.get('test_key'))  # 应输出'test_value'
    

2. 修正视图中的参数获取逻辑

你的视图使用request.data['token']获取GET请求的参数,但request.data仅处理POST/PUT等请求的请求体,GET参数需从request.query_params获取,否则会抛出KeyError(可能你测试时用了POST请求,但接口声明的是GET):

# views.py
@api_view(('GET',))
@throttle_classes([LowLevelThrottle])
def home_stats(request):
    token = request.query_params.get('token')
    if not token:
        return Response({'error': 'token missing'}, status=status.HTTP_400_BAD_REQUEST)
    
    if token == os.environ['api_token']:
        content = {
            'users': len(Profile.objects.all()),
            'posts': len(Post.objects.all()),
            'reactions': len(PostReaction.objects.all())
        }
        return Response(content, status=status.HTTP_200_OK)  # 无需手动json.dumps
    else:
        return Response({'error': 'invalid token'}, status=status.HTTP_401_UNAUTHORIZED)

3. 调整自定义限流类的继承逻辑

AnonRateThrottle仅对未通过DRF认证系统认证的请求生效,若你自行校验token但未集成DRF认证,理论上仍会被视为匿名用户,但为了更可靠的限流(支持按IP或token限流),建议继承SimpleRateThrottle并自定义缓存键:

# custom_throttles.py
from rest_framework.throttling import SimpleRateThrottle

class LowLevelThrottle(SimpleRateThrottle):
    scope = 'll'

    def get_cache_key(self, request, view):
        # 按客户端IP限流(适合匿名场景)
        ident = self.get_ident(request)
        # 若要按token限流(需先确保token已获取):
        # ident = request.query_params.get('token', self.get_ident(request))
        return self.cache_format % {
            'scope': self.scope,
            'ident': ident
        }

4. 清理冗余的全局配置

视图已通过@throttle_classes指定了限流类,无需再将其加入DEFAULT_THROTTLE_CLASSES,避免重复生效或冲突:

# settings.py
REST_FRAMEWORK = {
    # 移除DEFAULT_THROTTLE_CLASSES中的自定义限流类
    'DEFAULT_THROTTLE_RATES': {
        'll': '1/sec',
    }
}

验证修复

完成上述调整后,1秒内多次请求/home_stats接口,超出次数后应返回429 Too Many Requests状态码,说明限流生效。

内容的提问来源于stack exchange,提问作者kipteam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:39:22