Django HttpResponseRedirect

Question:

I have created a basic contact form, and when the user submits information, it should redirect to the “Thank You” page.

views.py:

def contact(request):
    # if no errors...
    return HttpResponseRedirect('/thanks/')

urls.py:

(r'^contact/$', contact),
(r'^contact/thanks/$', contact_thanks),

Both pages work at the hard-coded URL. However, when I submit the form on /contact/ it redirects to /contact (no ending slash), which is a nonexistent page (either a 404 or an error page telling me I need a slash).

What is the reason it not correctly redirecting, and how can I fix this?

UPDATE: the return HttpResponseRedirect('/contact/thanks/') is what I now have, but the problem is that the submit button (using POST) does not redirect to the URL — it doesn’t redirect at all.

Asked By: David542

||

Answers:

Use the Django APPEND_SLASH setting.

APPEND_SLASH

When set to True, if the request URL
does not match any of the patterns in
the URLconf and it doesn’t end in a
slash, an HTTP redirect is issued to
the same URL with a slash appended.
Note that the redirect may cause any
data submitted in a POST request to be
lost.

Answered By: aviraldg

I believe that apart from Aviral Dasgupta’s solution, OP also needs to change the relative url.

 return HttpResponseRedirect('/thanks/')

to

 return HttpResponseRedirect('/contact/thanks/')

/thanks/ should take the url to root: yoursite/thanks/ and not yoursite/contact/thanks/.

Answered By: user201788

It’s not the POST button that should redirect, but the view.

If not differently specified, the form (the HTML form tag) POSTs to the same URL. If the form is on /contact/, it POSTs on /contact/ (with or without slash, it’s the same).

It’s in the view that you should redirect to thanks. From the doc:

def contact(request):
    if request.method == 'POST': # If the form has been submitted...
        form = ContactForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            # Process the data in form.cleaned_data
            # ...
            return HttpResponseRedirect('/thanks/') # Redirect after POST
    else:
        form = ContactForm() # An unbound form

    return render_to_response('contact.html', {
        'form': form,
    })

Change /thanks/ to /contact/thanks/ and you’re done.

Answered By: vad

All of the responses are correct but a better approach is to give names to your URLs in urls.py and hint to them in views with reverse function (instead of hard coding URL in views).

urls.py:

(r'^contact/$', contact, name='contact'),
(r'^contact/thanks/$', contact_thanks, name='thanks'),

And hint them in views.py like this:

from django.urls import reverse

return HttpResponseRedirect(reverse('app_name:thanks'))

This is better for future approach and follow the DRY principle of Django.

Answered By: alireza sadeghpour

Just try this. It worked for me.

return HttpResponseRedirect('thanks/')

Note:- Remove the forward slash before

Answered By: Jasmeet Singh