Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

428
Views
How to queue requests in Django?

I manage a physical locker with Django (DRF). Users fill out a form, authenticate via link sent to their e-mail, authorize via a pin displayed on the locker.

My view should handle three cases:

  • If user authenticates and authorizes successfully, pin displayed on the locker is replaced with a generic message and the locker opens. (Already implemented)

  • If the user fails to authorize within 3 minutes, locker pin is replaced with a generic message.

  • If a new authorization request is made by user Foo, while authorization for user Bar is still incomplete, stack the request in a queue and wait for case 1. or case 2. to complete.

How can I:

  • Implement a request queue, such that the pin displayed on the locker does not get overridden/replaced when a new request comes in?
  • How can I wait 3 minutes for authorization to be completed before processing the next request?

View as is, in case it is useful:

   if request.method == 'POST':
        form = ConfirmationForm(request.POST)
        if form.is_valid():
            if pin == form.cleaned_data['pin']:
                open_bay(jwt_token=jwt[1], pin=pin)
                display_generic_message(jwt_token=jwt[1])
                lock_bay(jwt_token=jwt[1], pin=pin)
                return render(request, 'static/pages/request-success.html')
            else:
                pass
    else:
        form = ConfirmationForm()
    return render(request, 'static/pages/confirmation.html', {'form': form})
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

in your model which u save the authorization u need to add a field of date_created or date_requested and must be a datetime field . then on each request you can check if 3 minutes has passed from date_requested which you saved . you also need an is_authorized field to check if your user is authorized or not. we assume that you are getting the user from email you sent .

user = get_object_or_404(User,email=kwargs['email'])
if user.date_request + timedelta(minutes=3) > datetime.datetime.now():
   "do your authorzing stuff ..."
else:
     return HttpResponse("you need to wait 3 minutes to request again")
over 4 years ago · Santiago Trujillo Report

0

You would need to store when the last authorization started, clear that timestamp if the user puts in the pin.

# models.py
class LockerUserQueue(models.Model):

    user = models.ForeignKey(get_user_model())
    locker = models.ForeignKey("yourapp.Locker")
    created_at = models.DateTimeField(index=True, auto_now_add=True)


class Locker(models.Model):
    last_authorization = models.DateTimeField(null=True, blank=True)
    user_queue = models.ManyToManyField(through=LockerUserQueue)

    class BadPin(Exception):
        pass

    def enqueue_user(self, user):
        self.user_queue.add(user)

    def process_authorization(self, user):
        # do authorization for user

    def process_pin(self, user, pin):
        self.last_authorization = None
        if validate_pin(user, pin):
            # pin OK logic
        else:
            raise self.BadPin

# views.py
def authorize_user(request, locker_id):
    locker = get_object_or_404(pk=locker_id)
    locker.enqueue_user(request.user)
    locker.save()
    return render(request, "authorization_started.html")

def open_bay_with_pin(request, locker_id):
    locker = get_object_or_404(pk=locker_id)
    pin = get_pin_from_request(request)
    try:
        # No matter if the pin is correct, the locker.last_authorization is cleared
        locker.process_pin(user, pin)
    except locker.BadPin:
        return render(request, "bad_pin.html")
    finally:
        locker.save()
    return render(request, "good_pin.html")



# management/commands/process_queue.py
# you would run this by
# $ python manage.py process_queue
class Command(BaseCommand):

    @transaction.atomic
    def process_queue(self):
        # you probably want to put the 3 min delay in your settings.py
        # so you don't end up with a magic value here
        for locker in LockerUserQueue.objects.filter(
            Q(locker__last_authorization__isnull=True)|Q(locker__last_authorization__gt=now() - timedelta(minutes=3))
        ).order_by("created_at").values_list("locker", flat=True).distinct():
            locker.process_authorization()

    def handle(self):
        while True:
            self.process_queue()
            # you don't want to keep querying the DB when there's nothing in the queue
            sleep(5)

The code above shows how you would do it using the database as the queue, in a low volume use case this should be just fine. If the volume is high, I would store the locker last_authorization in faster storage, like redis, the queue can be maintained in redis as well. But the logic behind would be the same.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!