Prevent submitting multiple forms in Django

I am looking for a general way to prevent multiple forms from appearing. I found this approach that looks promising. Although I do not want to include this fragment in all my views. Most likely, this is easier to do with a query processor or middleware.

Best Practice Recommendations?

+4
python django forms hash
Mar 27 '13 at 23:12
source share
4 answers

Client side, start with JavaScript. You can never trust a customer, but its beginning.

i.e.

onclick="this.disabled=true,this.form.submit(); 

On the server side, you can “insert something into the database, that is, the checksum. If its entries that you insert into the database, use model.objects.get_or_create() to force uniqueness at the database level, you should use unique_together.

Finally : HTTPRedirect is best. The method that I use when the user processes the payment is to simply send HTTPRedirect () to the thanks / conformation page. Thus, the form update will not be resubmitted, and if they return and try to submit the form again (without updating the form), the Django site request routine (CSRF) will fail!

+11
Mar 27 '13 at 11:23
source share

I am also trying to find a good way to prevent the creation of double entries when the user dbl-click on the submit button. This is not about a PRG problem that is easily fixed by redirection.

So, given this basic problem, a solution with HTTPRedirect on the server side does not help.

On the client side, I found two problems when I disabled the button before sending:

  • When validating HTML5, form.submit() will be intercepted by the browser if the form is invalid => the submit button is still disabled=true .
  • When the user submits the form and returns to the browser history, the DOM will be loaded from the browser cache => submit button is still disabled=true .

So here is my workaround for the first client problem (HTML5 check):

 isFormHtml5Valid(form) { for(var el of form.querySelectorAll('input,textarea,select')){ if(!el.checkValidity()) return false; } return true; } mySubmitButton.onclick = function() { if(this.form && isFormHtml5Valid(this.form)) this.disabled=true; this.form.submit(); } 

I'm trying to find a client side workaround for a second client side problem (DOM browser cache), but nothing works (onbeforeunload, ...). Therefore, the workaround that I currently use for the "browser cache" is to add the @never_cache decoration at the top of the corresponding views (on the server side, specify on the client side, so as not to cache). Please let me know if you have a better workaround.

Last but not least, I would really like to fix this problem on the server side . The CSRF solution seems unusable because the CSRF token is generated by the session (not for each form). So, here is the status of my work and my question:

  • Fixing this problem on the client side is fine, but it doesn’t look like to me. How could we avoid checking this multiple form submission on the server side?

Let me know if you have a good solution for this.




Edit 1: Maybe a small part of the answer: the synchronizer token (or Déjà vu)

But in Django, I did not find any effect.

+1
Sep 07 '16 at 11:06
source share

Use HttpResponseRedirect

create a new view (say thank_you ) to successfully display the message after submitting the form and returning the template.

After the form is submitted successfully, return the HttpResponseRedirect ("/ thank-you /") to the new window with thanks

 from django.http import HttpResponseRedirect def thank_you(request, template_name='thank-you.html'): return render_to_response(template_name,locals(),context_instance=RequestContext(request)) 

and in urls.py

 url(r'^thank-you/$','thank_you', name="thank_you") 

Multiple forms are represented because when the page refreshes the same URL, which calls up the same view again and again and therefore several records stored in the database. To avoid this, we must redirect the response to a new url / view, in order to refresh the next temporary page, it will hit this new URL.

+1
Mar 15 '17 at 6:56
source share
  • After a successful submission, respond with a redirect so that the reload does not cause another submission
  • Disable submit button when submitting form

As for # 2, it's best to do this in the onsubmit handler rather than onclick for the submit button. This will handle cases like multiple submit buttons or if there is some kind of HTML5 client side validation. In jQuery, it looks something like this:

 $('#edit_form').submit( function(event) { // disable to avoid double submission $('#submit_button').attr('disabled', true); }); 

However, one problem that this is not talking about is that the user cancels the submission of the part. For example, if you press "send", and then immediately press "Esc", the browser will stop sending, but the "send" button is already disabled.

In addition, it is possible to get the form represented by pressing "enter", and this solution would not hurt to send this form twice.

0
Dec 12 '17 at 15:03
source share



All Articles