Django: Redirect to current page after POST method shows re-post warning
Solution 1
If your form action is set to ".", you don't need to do a redirect. The browser warning is not within your control to override. Your code can be greatly simplified:
# Assuming Django 1.3+
from django.shortcuts import get_object_or_404, render_to_response
def template_conf(request, temp_id):
template = get_object_or_404(ScanTemplate, pk=temp_id)
temp_form = ScanTemplateForm(request.POST or None, instance=template)
if request.method == 'POST':
if form.is_valid():
form.save()
# optional HttpResponseRedirect here
return render_to_response('arachni/web_scan_template_config.html',
{'template': template, 'form': temp_form})
This will simply persist your model and re-render the view. If you want to do an HttpResponse Redirect to a different view after you call .save()
, that will not cause the browser to warn you that the POST data has to be re-submitted.
Also, there's no need, and it's not good practice, to hard-code your URL patterns that you would do a redirect to. Use the reverse
method from django.core.urlresolvers. It will make your code a lot easier to refactor later, should your URLs need to change.
Solution 2
It looks like you are coming across a bug in Chrome 25 (see Chromium issue 177855), which is handling handling redirection incorrectly. It has been fixed in Chrome 26.
Your original code is correct, although it can be simplified slightly as Brandon suggests. I recommend you do redirect after a successful post request, as it prevents the user from accidentally resubmitting data (unless their browser has a bug!).
Comments
-
Shang Wang almost 2 years
I'm so confused at the problem that I have, I wish someone can point out my mistake.
I have a method in views.py that bounds to a template that has a form in it. The code looks like this:
def template_conf(request, temp_id): template = ScanTemplate.objects.get(id=int(temp_id)) if request.method == 'GET': logging.debug('in get method of arachni.template_conf') temp_form = ScanTemplateForm(instance=template)) return render_response(request, 'arachni/web_scan_template_config.html', { 'template': template, 'form': temp_form, }) elif request.method == 'POST': logging.debug('In post method') form = ScanTemplateForm(request.POST or None, instance=template) if form.is_valid(): logging.debug('form is valid') form.save() return HttpResponseRedirect('/web_template_conf/%s/' %temp_id)
The behavior of this page is this: when I press "submit" button, the program enters the
POST
branch, and successfully executed everything in the branch. Then theHttpResponseRedirect
only redirect to current page(that url is current url, I think should be equal to.
). After thatGET
branch got executed since I redirect to current page, and the page did return successfully. However, if I refresh the page at this time, the browser returns a confirm warning:The page that you're looking for used information that you entered. Returning to that page might cause any action you took to be repeated. Do you want to continue?
If I confirm, the post data will be posted to the backend again. Seems like the browser is still holding previous POST data. I don't know why this happens, please help. Thanks.
-
Shang Wang about 11 yearsThanks very much for your suggestions. Learned a lot. One question: is 'render' method new in Django 1.4? I'm currently having 1.3 installed.
-
Brandon Taylor about 11 yearsYes, render is only available in 1.4.x+. If you're using 1.3, you'll need to use render_to_response.
-
Shang Wang about 11 yearsIt's never too late to answer the question! Thanks for the information and confirmation with my code. +1
-
Brandon Taylor over 8 years@Andrey 99% of the time I will always do a redirect after a POST request. I'm not sure why the OP wanted to just render the same view over.