How to handle parallel request in Django Rest Framework?

django rest framework throttling
django concurrent requests
django rest framework cache
django rest framework post example
handle multiple requests python
django rest framework patch
how to reduce response time of rest api in django
how does a web server handle multiple requests

I have created an API in DRF which accepts POST request with some data, But sometimes I feel that same requests are coming in parallel which causing the duplicate data in DB.

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

Use can send same feedback multiple time. Let's think it's an open API so anyone can consume it and in someone's app user clicks multiple time on button and I received multiple requests but data should be saved only one time.

I have tried by adding a BooleanField to Student table and used the following code to prevent it. But as multiple requests coming in parallel they can read the same value 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() 

I want to process only one API call on same endpoint and same IP at a time. How can I achieve it?

Updated

I have researched and found that we can add lock on table or object but I am looking for prevention on requests level

It sounds like you want to enforce some uniqueness in your model. You didn't provide any code, but here's a Student model, for example:

class Student
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=20)
    date_of_birth = models.DateField()
    admission_date = models.DateField()

    class Meta:
        unique_together = ['first_name', 'last_name', 'date_of_birth', 'admission_date']

Then, in your view that creates the student, you'll have to return an HTTP error code if the student already exists:

def create_student(request):
    new_student = Student(first_name=request.POST['first_name'],
                          last_name=request.POST['last_name'],
                          date_of_birth=request.POST['date_of_birth'],
                          admission_date=request.POST['admission_date'])
    try:
        new_student.save()
    except IntegrityError:
        response = HttpResponse("Student already created")
        response.status_code = 409    # code for conflict
        return response

    return HttpResponse("OK, new student created")

NOTE: You might want to think about your design if you will have multiple duplicate students being created in parallel.

Throttling, Throttles indicate a temporary state, and are used to control the rate of requests that clients can make to an API. As with permissions, multiple throttles may be used  Request objects. REST framework introduces a Request object that extends the regular HttpRequest, and provides more flexible request parsing. The core functionality of the Request object is the request.data attribute, which is similar to request.POST, but more useful for working with Web APIs. request.POST # Only handles form data.

The parallel requests can be prevented by using throttling in DRF. Basic configuration are as follow:

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 can be replaced by second, minute, hour or day as per the requirement.

If you want to configure different rate limits for different request method like GET, POST and PUT. You can simply create your own throttle. Here is the example of throttle for GET request.

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

Refer http://www.django-rest-framework.org/api-guide/throttling/ for more details

How to handle parallel PUT/PATCH requests in Django Rest , How to handle parallel PUT/PATCH requests in Django Rest Framework? (​Overwrite issue) - django. With the Django REST Framework, you can generate a human-friendly HTML output for each resource when an HTML format is requested. These pages allow you to easily browse through resources, as well as build in forms to submit data to the resources using POST, PUT, and DELETE. Let’s test our API with the browsable REST Framework interface.

If you still have issues, you can do in this way:

from django.db import transaction
import datetime


@transaction.atomic
def my_view_function(student: Student):

    student = Student.objects.filter(
        id=student.id, 
        last_feedback=student.last_feedback
    ).update(
        last_feedback=datetime.datetime.now()
    )

    if student is True:
        # feedback models and rules
        pass

Then when you store it on database you will do:

try:
    my_view_function(student)
except:
    print("Unable to issue the feedback as other feedback is just issued")

how do you make django handle multiple requests? : django, my problem comes that when i for example make a call for an api to retrieve data it gets stuck there and if i for example have 2 tabs with the website and make that​  Django REST framework is a best toolkit to create an API. It supports both ORM and Non-ORM data sources. It can support regular function based view and class based views. 1) Installation of Django REST framework. pip install djangorestframework 2) Add 'rest_framework' in 'INSTALLED_APPS' settings.py. INSTALLED_APPS = ( 'rest_framework',

Web API performance: profiling Django REST framework, This includes the mechanics of REST framework's authentication, permissions, throttling, content negotiation and request/response handling. Django Rest Framework gives us several options for setting permissions: at a project-level, view level, or object level. In this case we will implement the last option and create a custom permission we can add to our SnippetDetail view class. Create a new permissions.py file.

tanwanirahul/django-batch-requests: Combine multiple http , 40 million developers working together to host and review code, manage projects, and Django batch requests allow developers to combine multiple http requests into a For such a request, batch api replies back with list of HTTP response objects. batch_requests will now execute the individual requests in parallel. REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler' } Note that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the HTTP_400_BAD_REQUEST responses that are returned by the generic views when

Make (serializer) validation safe for concurrent requests · Issue #409 , REST Framework (DRF) doesn't handle IntegrityErrors nicely. IntegrityErrors are only catched at a very late stage in the request-response cycle  Django REST framework is a powerful and flexible toolkit for building Web APIs. Some reasons you might want to use REST framework: The Web browsable API is a huge usability win for your developers. Authentication policies including packages for OAuth1a and OAuth2. Serialization that supports both ORM and non-ORM data sources.

Comments
  • @dfundako I have researched a lot and tried multiple solutions but none of them works for me perfectly that's why I posted my question here.
  • maybe you can solve on client side too, disable submit button until your request ends.
  • @aliva You are correct, but we should handle it on server side too because API can be open for anyone.
  • it's not a good idea to put unique together on all fields. Let model have two fields user and message and user can send same message multiple time, but I want to prevent this when API hit is parallel from same IP.
  • I have updated the question, Please have a look again.