[英]Override Settings for Tests of Django Rest Framework Throttling
我正在尝试测试自定义用户限制:
def get_user_rate(user):
# Returns tupple (user plan quota, total seconds in current month)
class SubscriptionDailyRateThrottle(UserRateThrottle):
# Define a custom scope name to be referenced by DRF in settings.py
scope = "subscription"
def __init__(self):
super().__init__()
def custom_throttle_success(self):
"""
Inserts the current request's timestamp along with the key
into the cache.
"""
self.history.insert(0, self.now)
self.cache.set(self.key, self.history, self.duration)
return True
def allow_request(self, request, view):
"""
Override rest_framework.throttling.SimpleRateThrottle.allow_request
Check to see if the request should be throttled.
On success calls `throttle_success`.
On failure calls `throttle_failure`.
"""
if request.user.is_authenticated:
limit, duration = get_user_rate(request.user)
# Override the default from settings.py
self.duration = duration
self.num_requests = limit
self.key = self.get_cache_key(request, view)
if self.key is None:
return True
self.history = self.cache.get(self.key, [])
self.now = self.timer()
# Drop any requests from the history which have now passed the throttle duration
while self.history and self.history[-1] <= self.now - self.duration:
self.history.pop()
if len(self.history) >= self.num_requests:
return self.throttle_failure()
return self.custom_throttle_success()
在settings.py
中,为了安全起见,我添加了 10/秒的默认油门速率(它首先在DEFAULT_THROTTLE_CLASSES
上传递):
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.UserRateThrottle',
'api.throttling.SubscriptionDailyRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'user': '10/second',
}
}
我要编写的测试非常简单,如果我有一个给定计划的用户,我想检查该用户是否可以在不被限制的情况下提出 N 个请求:
class TestThrottling(TestCase):
def test_plan_quota(self):
user = User.objects.create_user(username='test', email='test@email.com', password='test')
Plan.objects.create(user=user, plan=1) # plan 1 has N requests per month
token, _ = Token.objects.get_or_create(user=user)
auth_client = Client(HTTP_AUTHORIZATION='Token ' + token.key)
url = reverse('some_endpoint')
for k in range(N): # Being N the user plan quota
response = auth_client.get(url)
self.assertNotEqual(response.status_code, 429)
response = auth_client.get(url)
self.assertEqual(response.status_code, 429)
我遇到的问题是设置中默认的 10/秒速率,因为它在达到用户计划配额之前就中断了循环。 我想从设置中删除此默认速率以检查我的节流是否正常,我还可以设置一个计时器以避免每秒发出超过 10 个请求,但计划配额非常高并且需要数小时。 我尝试覆盖设置添加:
# Override default user throttling
new_config = settings.REST_FRAMEWORK.copy()
new_config['DEFAULT_THROTTLE_CLASSES'] = ['api.throttling.SubscriptionDailyRateThrottle']
@override_settings(REST_FRAMEWORK=new_config)
def test_plan_quota(self):
...
这样我可以删除测试的默认 10/秒速率,不幸的是这不起作用,因为有时 DRF不会更新设置。 关于如何解决这个问题的任何建议?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.