Does A Library To Prevent Duplicate Form Submissions Exist For Django?
Solution 1:
You can use a session to store the hash
import hashlib
defcontact(request):
if request.method == 'POST':
form = MyForm(request.POST)
#join all the fields in one string
hashstring=hashlib.sha1(fieldsstring)
if request.session.get('sesionform')!=hashstring:
if form.is_valid() :
request.session['sesionform'] = hashstring
#do some stuff...return HttpResponseRedirect('/thanks/') # Redirect after POST elseraise SubmissionWasDuplicate("duplicate")
else:
form = MyForm()
With this approach (not deleting the session cookie) the user can't re-store the data util the session expires, by the way, i'm assuming that exist something who identify the user who send the data
Solution 2:
One easy solution to this problem is to add a unique hash to each form. Then you can have a rolling table of current forms. When a form is submitted, or the hash gets too old, you can expire it out of your table, and reject any form which does not have a matching hash in your table.
The HTTPRedirect is the correct way to do it, as previously mentioned.
Unfortunately, even Django's own built in admin is prone to problems related to this issue. In some cases, the cross-site scripting framework can assist to prevent some of this, but I'm afraid the current production versions just don't have this built in.
Solution 3:
To be honest, your best bet (easy and good practice) is to issue a HTTPRedirect() to the thank you page, and if the thank you page is the same one as the form, that's OK. You can still do this.
Solution 4:
Kristian Damian's answer is really a great suggestion. I just thought of a slight variation on that theme, but it might have more overhead.
You could try implementing something that is used in django-piston for BaseHandler
objects, which is a method called exists()
that checks to see if what you are submitting is already in the database.
From handler.py (BaseHandler):
defexists(self, **kwargs):
ifnot self.has_model():
raise NotImplementedError
try:
self.model.objects.get(**kwargs)
returnTrueexcept self.model.DoesNotExist:
returnFalse
So let's say make that a function called request_exists()
, instead of a method:
if form.is_valid()
if request_exists(request):
# gracefully reject dupe submissionelse:
# do stuff to save the request
...
# and ALWAYS redirect after a POST!!return HttpResponseRedirect('/thanks/')
Solution 5:
It is always good to use the redirect-after-post method. This prevents user from accidently resubmitting the form using refresh function from the browser. It is also helpful even when you use the hash method. It's because without redirect after a POST, in case of hitting Back/Refresh button, user will see a question message about resubmitting the form, which can confuse her.
If you do a GET redirect after every POST, then hitting Back/Refresh won't display this wierd (for usual user) message. So for full protection use Hash+redirect-after-post.
Post a Comment for "Does A Library To Prevent Duplicate Form Submissions Exist For Django?"