3

There's some functionality on our Django app that displays a link to refresh some information from our version control system. This is simply a link, and when they hit that URL the actions of going to version control, getting the information, checking it against the database and updating the database are performed.

Recently we had a user click the 'refresh' button twice for one asset. This resulted in the URL being hit twice, so the operations were performed twice and eventually a duplicate entry was created in our database.

We need to do something to remove the possibility of the user clicking that button twice. Should we move from a link to a javascript button? Should we set some flag in request.session as soon as the first click happens, then unset it upon completion, and always check that flag when performing a refresh? Those are just two ideas that seem feasible, but I really don't know.

Nathan
  • 4,545
  • 6
  • 32
  • 49
  • 2
    Why is a page request, causing a database entry? I'm guessing it's not a POST. – John C Jun 27 '11 at 21:28
  • Oops. This is our first webapp, but I should've caught that. Yeah - this is a get. There's a column where we generate either a 'view' link (if our DB is up to date with VC) or a 'refresh' link (if our DB is not up to date with VC). The 'view' is clearly a GET, but 'refresh' should be a POST. Does that mean the model of having it be a link will not work? – Nathan Jun 27 '11 at 21:39

3 Answers3

4

You should use POST request and redirect after it, really.

Also, to prevent double submitting, you can employ a solution like one from this question: Does a library to prevent duplicate form submissions exist for django?. You can store a key refreshing_vcs in request.session and check its value in your view. If the data is already being refreshed, then you can redirect user to another page and tell to wait a bit.

Completely another way would be to setup a django-celery task (or simply use cron) to perform updates at regular intervals automatically, but I don't know whether it suit your requirements.

Community
  • 1
  • 1
Anton Strogonoff
  • 32,294
  • 8
  • 53
  • 61
  • Yeah, we're incorrectly using a GET here. Changing to a POST and adding the a flag to the session seems like the solution. Thanks! – Nathan Jun 27 '11 at 21:41
0
from django.views import View
from django.shortcuts import render, redirect 

class MyView(View):
    def get(self, request):
         return render(request, 'get.html')
    def post(self, request):
        # handle your post here
        # maybe you had a form that was filled, handle it here
        # then instead of returning a HttpResponse
        # use a redirect, that way, a refresh won't result in the 
        # post method been called twice. 
        # note if you want, you can also safely redirect to the same view
        return redirect('/my-login-view')

looking at the django code the redirect functions arguments can be:
1. A model
2. A view name or
3. A URL

Komu
  • 14,174
  • 2
  • 28
  • 22
-1

That is the best solution, however you could disable the button onclick by adding a disabled attribute to the button equalling 'true'

With jQuery: $('#yourButtonId').attr("disabled", true);

Ben Taliadoros
  • 7,003
  • 15
  • 60
  • 97