why will HttpResponseRedirect prevent re submit of form?

1,514 views
Skip to first unread message

Mingming Wang

unread,
Dec 18, 2010, 11:06:47 AM12/18/10
to django...@googlegroups.com
From the tutorial of Django, there is the following code in here

Who knows the mechanism behind a redirect or a direct response? Refer the comments below. Thanks a lot!
from django.shortcuts import get_object_or_404, render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.template import RequestContext
from polls.models import Choice, Poll
# ...
def vote(request, poll_id):
    p = get_object_or_404(Poll, pk=poll_id)
    try:
        selected_choice = p.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the poll voting form.
        return render_to_response('polls/detail.html', {
            'poll': p,
            'error_message': "You didn't select a choice.",
        }, context_instance=RequestContext(request))
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls.views.results', args=(p.id,)))

Javier Guerra Giraldez

unread,
Dec 19, 2010, 6:36:58 AM12/19/10
to django...@googlegroups.com
On Sat, Dec 18, 2010 at 11:06 AM, Mingming Wang <mingo...@gmail.com> wrote:
> From the tutorial of Django, there is the following code in here
> Who knows the mechanism behind a redirect or a direct response? Refer the
> comments below. Thanks a lot!

HttpResponseRedirect returns a 301 or 302 response code to the
browser, instead of more common 200 (ok), or 404 (not found). That
simply instructs the browser to load the given URL. The interesting
part is that that given URL replaces the original (POST) one in the
browser's history.

for example, this is what happens on the wire:

<- GET /yourapp/voteform/
-> 200 OK (html with form)
<- POST /yourapp/vote (params)
-> 301 Redirect (/yourapp/voteresults/)
<- GET (/yourapp/voteresults/)
-> 200 OK (html with results)

but this is what gets stored in the history:

1:
action: GET /yourapp/voteform/
cache: html with form (filled)

2:
action: GET /yourapp/voteresult/
cache: html with results


see? no traces of the POST. if you hit 'back' in the browser, you go
to the form! the POST ceases to be an event, since from the point of
view of the browser, its only result is to go to the /voteresult/
page.

Of course, the user is free to go back and hit the submit button
again, but he's not presented with that cryptic "post again?" dialog.

--
Javier

Mingming Wang

unread,
Dec 20, 2010, 5:02:50 AM12/20/10
to django...@googlegroups.com
Thanks a lot Javier! It takes me days to understand this.

Hm...what if we don't use Redirect, what will happen in the wire? is it the following? If so, then no re submit problem lor. I must missed something out.
<-  GET /yourapp/voteform/
-> 200 OK (html with form)
<- POST /yourapp/vote   (params)
-> 200 OK (html with results)

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.


Tom Evans

unread,
Dec 20, 2010, 5:52:50 AM12/20/10
to django...@googlegroups.com
On Mon, Dec 20, 2010 at 10:02 AM, Mingming Wang <mingo...@gmail.com> wrote:
> Thanks a lot Javier! It takes me days to understand this.
> Hm...what if we don't use Redirect, what will happen in the wire? is it the
> following? If so, then no re submit problem lor. I must missed something
> out.
> <-  GET /yourapp/voteform/
> -> 200 OK (html with form)
> <- POST /yourapp/vote   (params)
> -> 200 OK (html with results)
>

The browser stores the state that a page was requested with. If at
this point, the user clicks refresh in their browser, then a browser
will typically resubmit the form, which is sub-optimal. By redirecting
to the appropriate page, you avoid this issue.

A common pattern with CRUD like queries is to redirect after any
modifying action, even if it is to the same page.

Cheers

Tom

Reply all
Reply to author
Forward
0 new messages