使用django ratelimit对每个用户的视图进行计数

使用django ratelimit对每个用户的视图进行计数,django,Django,为了限制前端某些模型的表单帖子,我最近开始使用。我想通过将编辑限制在可接受的数量来防止误用 我已经让django Rate Limit在基于IP的表单上为POST操作工作。但是,我想根据经过身份验证的用户限制表单。似乎可以用这个论点,但我就是不知道它是如何运作的。在使用django Rate Limit之前有人这样做过吗?或者可能知道一种更好的方法来限制每个用户提交表单?下面的方法对您很有用 from django.db import models from django.shortcuts i

为了限制前端某些模型的表单帖子,我最近开始使用。我想通过将编辑限制在可接受的数量来防止误用


我已经让django Rate Limit在基于IP的表单上为POST操作工作。但是,我想根据经过身份验证的用户限制表单。似乎可以用这个论点,但我就是不知道它是如何运作的。在使用django Rate Limit之前有人这样做过吗?或者可能知道一种更好的方法来限制每个用户提交表单?

下面的方法对您很有用

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

如果您希望根据经过身份验证的用户(即request.user)对限制进行评级,则可以使用user作为密钥

根据官方文档,这里是关键用户的用法

“用户”-使用request.user中的适当值。请勿与未经身份验证的用户一起使用

下面是装饰器示例:

@ratelimit(block=True, rate='1000/m', key='user' group='ext_api')
您可以浏览键的所有常用选项: