【问题标题】:How can I allow a user to only access a view once every 30 minutes in Django?如何允许用户在 Django 中每 30 分钟仅访问一次视图?
【发布时间】:2020-04-27 16:02:03
【问题描述】:

我正在构建一个允许用户更新网页的应用,但我想限制任何用户每 20-30 分钟进行一次更新。我可以简单地将这个逻辑添加到视图定义中吗?

@login_required
def update_options(request):
    ...
    # logic to determine how much time passed since the user visited
    ...
    return render(request, 'main/update-options.html')

【问题讨论】:

  • 最简单的方法是使用 Django 的缓存框架来设置一个基于用户 ID 的缓存键,具有较长的过期时间(例如 60 分钟)。否则,您可以添加带有时间戳的新模型字段,或使用第三方工具,例如 redis 或 memcached。

标签: python django django-views user-permissions time-limiting


【解决方案1】:

我会做这样的事情。我没有测试它,但它应该是关闭的。基本上使用 request.session 来跟踪上次更新。

from datetime import datetime

def update_options(request):
    if request.session['last_access'] is None or (datetime.now() - request.session['last_access']).days * 24 * 60 > 30:
        'YOUR CODE HERE'
        request.session['last_access'] = datetime.now()
    else:
        'TOO MANY TRIES'
    return render(request, 'main/update-options.html')

【讨论】:

    【解决方案2】:

    我想出了一个非常简单的方法来做到这一点,尽管建议的答案似乎是另一种似是而非的方法。我在我的模型中添加了一个字段,该字段将在用户发布更新后 10 分钟内保存一个值。然后我可以引用该字段并检查当前时间是否大于(晚于)用户上次更新后的 10 分钟。

    models.py

    class Update(models.Model):
        update = models.IntegerField(null=True, blank=True)
        user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
        date = models.DateTimeField(auto_now=True) # datetime of object creation
        next_allowed_update = models.DateTimeField(
                default=datetime.now()+timedelta(minutes=10)-timedelta(hours=5) # adjust for UTC
            )
        location = models.CharField(max_length=30, default='none')
    

    views.py

    @login_required
    def update_options(request):
        # user can only update once every 10 minutes : 10 set in model
        user_latest_update = Update.objects.filter(user=request.user).latest('id')
        current_time = datetime.now().replace(tzinfo=None)   
        next_allowed_update = user_latest_update.next_allowed_update.replace(tzinfo=None)
    
        remaining = str(next_allowed_update - current_time).split(':')
        minutes_remaining = int(remaining[1].lstrip("0")) + 1
        if current_time > next_allowed_update:
            return render(request, 'main/update-options.html')
        else:
            return render(request, 'main/update-denied.html', {'time_remaining': minutes_remaining})
    

    模板

    {% extends "main/base.html" %}
    
    {% block content %}
    <div class="container">
        <h1>You can update again in {{ time_remaining }} minute</h1>
    </div>
    {% endblock content %}
    

    此解决方案还允许我渲染视图并传入一个值以显示用户可以进行另一次更新之前的分钟数

    【讨论】:

      猜你喜欢
      • 2015-01-03
      • 1970-01-01
      • 2017-03-08
      • 2017-07-28
      • 1970-01-01
      • 1970-01-01
      • 2022-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多