Django: Redirect to current page after POST method shows re-post warning

17,705

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!).

Share:
17,705
Shang Wang
Author by

Shang Wang

(╯°□°)╯︵ ┻━┻

Updated on July 20, 2022

Comments

  • Shang Wang
    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 the HttpResponseRedirect only redirect to current page(that url is current url, I think should be equal to .). After that GET 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
    Shang Wang about 11 years
    Thanks 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
    Brandon Taylor about 11 years
    Yes, render is only available in 1.4.x+. If you're using 1.3, you'll need to use render_to_response.
  • Shang Wang
    Shang Wang about 11 years
    It's never too late to answer the question! Thanks for the information and confirmation with my code. +1
  • Brandon Taylor
    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.