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

基于用户类型的DRF动态限流配置失效问题及实现指导

问题分析与解决方案

核心配置错误

你当前的问题根源在于保留了DRF默认的限流类,导致自定义逻辑被覆盖:

  1. settings.py中DEFAULT_THROTTLE_CLASSES仍包含AnonRateThrottle和UserRateThrottle,这两个类会优先对所有用户生效,忽略你的自定义规则
  2. 自定义限流类未被加入全局配置,且存在拼写错误(PrivatPaidUserThrottle应为PrivatePaidUserThrottle)

方案一:拆分独立限流类(清晰直观)

创建三个分别对应不同用户类型的限流类,通过allow_request方法判断是否应用当前规则:

1. 编写自定义限流类(在app下新建throttling.py)

from rest_framework.throttling import AnonRateThrottle, UserRateThrottle

class StaffRateThrottle(UserRateThrottle):
    scope = 'staff'

    def allow_request(self, request, view):
        # 仅对staff用户应用此限流
        if not request.user.is_authenticated or not request.user.is_staff:
            return True
        return super().allow_request(request, view)

class NormalUserRateThrottle(UserRateThrottle):
    scope = 'normal_user'

    def allow_request(self, request, view):
        # 仅对非staff的认证用户应用此限流
        if not request.user.is_authenticated or request.user.is_staff:
            return True
        return super().allow_request(request, view)

class CustomAnonRateThrottle(AnonRateThrottle):
    scope = 'anon'

2. 更新settings.py配置

替换默认限流类,配置对应速率:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [],
    'DEFAULT_THROTTLE_CLASSES': [
        'your_app_name.throttling.CustomAnonRateThrottle',
        'your_app_name.throttling.NormalUserRateThrottle',
        'your_app_name.throttling.StaffRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/day',
        'normal_user': '100/day',
        'staff': '1000/day',
    },
}

方案二:单类动态切换限流规则(简洁高效)

用一个类统一处理所有用户类型,通过动态切换scope实现差异化限流:

1. 编写统一限流类

from rest_framework.throttling import SimpleRateThrottle

class DynamicUserRateThrottle(SimpleRateThrottle):
    def get_cache_key(self, request, view):
        # 根据用户类型动态设置scope
        if not request.user.is_authenticated:
            self.scope = 'anon'
            return self.cache_format % {
                'scope': self.scope,
                'ident': self.get_ident(request)
            }
        else:
            self.scope = 'staff' if request.user.is_staff else 'normal_user'
            return self.cache_format % {
                'scope': self.scope,
                'ident': request.user.pk
            }

    def allow_request(self, request, view):
        self.rate = self.get_rate()
        self.num_requests, self.duration = self.parse_rate(self.rate)
        return super().allow_request(request, view)

2. 更新settings.py配置

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [],
    'DEFAULT_THROTTLE_CLASSES': [
        'your_app_name.throttling.DynamicUserRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/day',
        'normal_user': '100/day',
        'staff': '1000/day',
    },
}

关键注意事项

  1. 移除默认限流类:必须确保DEFAULT_THROTTLE_CLASSES中不再包含AnonRateThrottle和UserRateThrottle,否则默认规则会优先生效
  2. 缓存清理:测试前清理DRF限流缓存(默认使用Django缓存),避免之前的测试残留计数导致误触发
  3. scope名称匹配:自定义限流类的scope必须与DEFAULT_THROTTLE_RATES中的键完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:10:56