要限制前端某些模型的表单帖子,我最近开始使用django-ratelimit。我希望通过限制修改 防止滥用达到可接受的数量。
我已经让django-ratelimit在基于IP的表单上进行POST操作。但是,我想根据经过身份验证的用户对表单进行限制。似乎可以使用keys参数,但我无法理解它是如何工作的。有人在使用django-ratelimit之前做过这个吗?或者可能知道一种更好的方法来限制每个用户的表单提交?
答案 0 :(得分:0)
以下方法对您有用
from django.db import models
from django.shortcuts import render_to_response
import datetime, random
class RequestRateManager(models.Manager):
def clean_expired(self):
"""Purges old entries from database.
If you use max_value's greater than 600 (seconds, ten minutes),
change the following line."""
l_time = datetime.datetime.now() - datetime.timedelta(seconds = 600)
self.get_query_set().filter(last_update__lt=l_time).delete()
class RequestRate(models.Model):
"""Implements a rate limit per IP.
value is increased at every request by the amount the request specifies,
which is meant to be the average number of seconds until the same
request could be made again.
value decreases at a rate of 1 per second until it is a 0.
"""
user_id = models.IntFied(blank=True, null=True)
last_update = models.DateTimeField()
value = models.FloatField()
objects = RequestRateManager()
def update(self):
this_update = datetime.datetime.now()
td = this_update - self.last_update
time_delta_sec = (float(td.days) * 3600.0 * 60.0 + float(td.seconds) +
float(td.microseconds) / 1000000.0)
self.value -= time_delta_sec
if self.value < 0:
self.value = 0
self.last_update = this_update
def request(self, seconds, max_value):
self.update()
if self.value + seconds < max_value:
self.value += seconds
self.save()
return True
else:
self.save()
return False
def limit(seconds, max_value, per_user=True, limit_exceeded_view=None,
limit_exceeded_template='connection_limit_exceeded.html'):
"""Makes a rate-limiting decorator"""
def default_limit_exceeded_view(*args, **kwargs):
return render_to_response(limit_exceeded_template)
limit_exceeded_view = limit_exceeded_view or default_limit_exceeded_view
def decorator(view):
def limited_view(request, *args, **kwargs):
if random.random() < 0.05:
RequestRate.objects.clean_expired()
if per_user:
ru = request.user.id
else:
ru = None
(l,tmp) = RequestRate.objects.get_or_create(user_id=ru,
defaults={ 'last_update': datetime.datetime.now(), 'value': 0 })
if l.request(seconds, max_value):
return view(request, *args, **kwargs)
else:
return limit_exceeded_view(*args, **kwargs)
return limited_view
return decorator
@limit(1,1)
def your_view(request):
pass
答案 1 :(得分:0)
如果您想根据经过身份验证的用户(即request.user)进行速率限制,则可以使用user
作为密钥
从官方文档中,这里是密钥user
'user' - 使用来自request.user的适当值。不要与未经身份验证的用户一起使用。
以下是示例装饰器:
@ratelimit(block=True, rate='1000/m', key='user' group='ext_api')
您可以浏览密钥的所有常用选项: