2014-09-30 58 views
0

要限制前端中某些模型的表單帖子,我最近開始使用django-ratelimit。我想防止誤用限制編輯到一個可接受的數額。爲每個用戶使用django ratelimit計數視圖

我有django-ratelimit工作在基於IP的窗體上的POST操作。然而,我想基於經過驗證的用戶對錶單進行限制。看來keys論點可以使用,但我不能讓我的頭瞭解它的工作原理。任何人在使用django-ratelimit之前完成此操作?或者也許知道更好的方式來限制每個用戶提交表單?

回答

0

如果你想限速基於經過驗證的用戶即request.user,您可以使用user關鍵

從官方的文檔,這裏是密鑰的用法user

'user' - 在request.user中使用合適的值。請勿與未經身份驗證的用戶一起使用。

下面的例子裝飾:

@ratelimit(block=True, rate='1000/m', key='user' group='ext_api') 

你可以通過關鍵的所有常用選項:

https://django-ratelimit.readthedocs.io/en/latest/keys.html

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