首页 > 解决方案 > 如何在 Django Rest Framework 中处理并行请求?

问题描述

我在DRF中创建了一个 API,它接受带有一些数据的 POST 请求,但有时我觉得相同的请求并行出现,导致数据库中的数据重复。

class Feedback(models.Model):
    user = models.ForeignKey(Student)
    message = models.CharField(max_length=255)

使用可以多次发送相同的反馈。让我们认为它是一个开放的 API,因此任何人都可以使用它,并且在某人的应用程序中,用户多次单击按钮,我收到了多个请求,但数据应该只保存一次。

我尝试通过添加一个表并使用以下代码来防止它BooleanFieldStudent但由于多个请求并行出现,它们可以读取相同的值True

if student.can_submit_feedback:
   student.can_submit_feedback = False
   student.save()
else:   
   # Code for saving feedback
   student.can_submit_feedback = True
   student.save() 

我想一次只处理同一端点和同一 IP 上的一个 API 调用。我怎样才能实现它?

更新

我研究并发现我们可以在表或对象上添加锁,但我正在寻找请求级别的预防措施

标签: djangoapidjango-modelsdjango-rest-frameworkdjango-views

解决方案


可以通过在 DRF 中使用限制来防止并行请求。基本配置如下:

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day', # 100 requests per day, 
        'user': '1000/day'
    }
}

day可以用second, minute,hourday根据需要替换。

如果您想为不同的请求方法(如 GET、POST 和 PUT)配置不同的速率限制。您可以简单地创建自己的油门。这是GET请求节流的示例。

class CustomBaseThrottle(rest_throttles.SimpleRateThrottle):
    """
    Limits the rate of API calls.

    The IP address, url and request method will be used for make unique key for anonymous user.
    The user id, url and request method will be used for make unique key for authenticated user.
    """
    scope = 'get'

    def get_cache_key(self, request, view):

        if request.method.lower() == self.scope:
            if is_authenticated(request.user):
                return "{}-{}-{}".format(request.user.id, request.path, request.method)
            return "{}-{}-{}".format(self.get_ident(request), request.path, request.method)
        return None

有关更多详细信息,请参阅http://www.django-rest-framework.org/api-guide/throttling/


推荐阅读