Django HttpResponseRedirect - python

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.

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.

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.

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/.

Just try this. It worked for me.
return HttpResponseRedirect('thanks/')
Note:- Remove the forward slash before

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.

Related

django: redirecting to another app's view not properly

App1 containing the form, after user fulfills and submits the form, the page will redirect to "Result" which is defined in App2
def input(request):
if request.method == 'POST':
form = Inputform(request.POST)
if form.is_valid():
cd = form.cleaned_data
print (cd['company'])
print (cd['region'])
return HttpResponseRedirect(reverse('result', args=(p.id,)))
The url is as below:
urlpatterns = patterns('',
url(r'^result/$','result.views.resultlist',name='result'),
url(r'^input', 'inputform.views.input',name='input'),
The thing is if I run http://127.0.0.1:8000/result on the browser, it works properly. But once I fulfill the form and click the submit, the page will redirect to:http://127.0.0.1:8000/result.html. And then there is error showing:
The current URL, result.html, didn't match any of these.
Any suggestion is highly appreciated. Thanks.
try
return redirect('result', args=(p.id,))

Redefining home in django

I'm working on a Django project in which I plan to make user profiles. My goal is to have a standard login page as seen here. After logging in, however, I want to redefine
url(r'^$', 'MyApp.views.home', name='home'),
to not show this page, but a user profile with the same url as home.
For example, www.example.com shows a login screen. After logging it, you're redirected to www.example.com, but you see your profile now.
How can I do this in Django?
You need simple check in view:
if request.user.is_authenticated():
return HttpResponseRedirect('/profileurl/')
An easy way to do it would be a redirect to another view:
MyApp.views
def home(request):
if request.user.is_authenticated():
redirect
else:
home page
If you want the actual url entry to load a different template than the home page, or a modified home page, you could just as easily render whatever template you wanted in response to the url request instead of issuing a redirect
This is generally how I would go about it. You can add context if needed.
views.py:
from django.shortcuts import render
def home(request):
if request.user.is_authenticated():
return user_home(request)
else:
return login_home(request)
def user_home(request)
return render(request, 'path/to/user_template.html')
def login_home(request)
return render(request, 'path/to/login_template.html')

Django froms submit action and HttpResponseRedirect difference

Referring from the form topic of django documentation, if in a view function I write,
if form.is_valid():
return HttpResponseRedirect('/thanks/')
And in the form template I give the action like,
<form action="/your-name/" method="post">
Then on submit the form will go to the view mapped tho /your-name/ url in urls.py but what about the HttpResponseRedirect('/thanks/') line in the function from where I rendering the form? If a form is valid then I save the form. but what will be the url in the action of the form. now def get_name(request): is the function mapped to /user/ url. I hope you understand my confusion here. need some help.
This is an exemple of the "post redirect get" pattern - if a post is succesfull (the form was valid and the processing went ok), it's good practice to return a redirect, which will be followed by a get from the user-agent on the url you redirected to. It avoids multiple submissions if the user try to reload the page.
Where you redirect to is up to you - you can just redirect to the same view (usually displaying a success message to the user), or redirect to another view.
As a side note: hardcoding urls is a bad practice in Django, you should use the url reverse feature instead.

login redirect to another app view

This is my project structure
project
app
login
manage.py
After successful login i want my user will be redirect to localhost:8000/app but currently it will redirect to http://localhost.com:8000/accounts/login/?next=/ because i set it up my login view as
def login_view(request):
if request.POST and form.is_valid():
user = form.login(request)
if user:
login(request, user)
return render_to_response('app/home.html',RequestContext)
else:
return HttpResponse('disabled account')
return render_to_response('login.html', form ,RequestContext)
i can't able to use HttpResponseRedirect(reverse('app.views.dashboard')) because dashboard view not exit in the same login views.py
if i import like
from app import views as app_dashboard or from app import dashboard
i am getting below error
Reverse for 'app.views.dashboard' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
final note, below is my login url currently
Sign in
Added:
app/urls.py
urlpatterns = patterns('app.views',
(r'^$', 'dashboard_view'),
project/urls.py
url(r"^", include("app.urls",)),
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
(r'^accounts/logout/$', 'django.contrib.auth.views.logout', {'next_page' : '/accounts/login'}),
First point: use named urls, cf https://docs.djangoproject.com/en/1.6/topics/http/urls/#naming-url-patterns - this should resolve your reverse problem.
Second point: you show the code for your own login view but your url.py and template's extract both refer to django.contrib.auth.views.login. Also, you specify a next param in your template's url, so django.contrib.auth.views.login do redirect you there, as explained in the FineManual(tm):
If called via POST with user submitted credentials, it tries to log the user in.
If login is successful, the view redirects to the URL specified in next.
(...)
Finally: you don't need to write you own view if all you want is to force the login view to always redirect to a same URL:
(...) If next isn’t provided, it redirects to settings.LOGIN_REDIRECT_URL (which defaults to /accounts/profile/). If login isn’t successful, it redisplays the login form.
IOW:
use named urls everywhere (name your own urls, and use urls names when calling reverse or the {% url %} templatetag)
get rid of the next=... in your templates
set your settings.LOGIN_REDIRECT_URL to your dashboard's url.
def login_view(request):
if request.POST and form.is_valid():
user = form.login(request)
if user:
login(request, user)
return redirect('/app/')
else:
return HttpResponse('disabled account')
return render_to_response('login.html', form ,RequestContext)
Change render response to redirect
give your required url to redirect

How to Call default home url in django when i logged out

Please visit this link for getting whole idea behind this question
How to Call loggedin username in Django url
Here i have discussed my points in this link but i didnt got specific answer for my issue that , when user loggedin i wanted it to be displayed in my url as
" 127.0.0.1:8000/username " as i got the solution in above link as create user defind HomeRedirectView which calls initially when user logsin. and it works successfully, but i got an issue when i logged out and revisit the url as " 127.0.0.1:8000/ " then this url automatically becomes " 127.0.0.1:8000/AnonymousUser " and am getting the error as "NoReverseMatch", for that i have to specifically write it into url as " 127.0.0.1:8000/home/ " then it works. So can any one suggest me how to make url as " 127.0.0.1:8000/home/ ". To know about what i have done uptill now ,please visit above link and you will come to know from the discussion.
Please suggest.
The solution you got there is not the right solution, the right solution is to use the LOGIN_REDIRECT_URL setting and point it to a view function, a named URL pattern or a direct URL.
Once a user is logged in using the default authentication mechanism of django, the request will automatically be redirected to this page.
Your second problem is when you logout a user, you want to be redirected to a specific URL. If you use the correct solution above, then all you need to do is:
Set LOGOUT_URL in your settings.py.
Create your logout view, it can be as simple as this example from the documentation:
from django.shortcuts import redirect
from django.contrib.auth import logout
def logout_view(request):
logout(request)
return redirect('/home/')
If you want to stick with your original solution, then modify it like this:
class HomeRedirectView(RedirectView):
pattern_name = 'home'
def get_redirect_url(self, *args, **kwargs):
if self.request.user.is_authenticated():
return "/user/{}/".format(self.request.user)
else:
return '/home/'
I think you are overcomplicating things a little, the following will allow you to redirect to a user home page if a user is logged in, or it will display an un-logged in view. I have made the assumption that the username in the URL is purely for display purposes (otherwise it could be a security issue for your application.
urls.py
urlpatterns = patterns('myapp.views',
url(r'^/$', 'home', name='home'),
url(r'^user/[-_.\w\d]+/$', 'user_home', name='user-home'),
)
views.py
from django.contrib.auth.models import User
from django.shortcuts import redirect, render, get_object_or_404
def home(request):
"""
Home page
"""
# If a user is authenticated then redirect them to the user page
if request.user.is_authenticated:
return redirect('user-home', request.user.username)
else:
return render(request, "myapp/home.html")
#login_required
def user_home(request):
"""
User specific home page, assume the username in URL is just for decoration.
"""
return render(request, "mpapp/home_user.html", {
"user": request.user
}

Categories