Reputation: 143
In Django 1.10, My redirect to other view via url or the viewname is not working.
The main urls.py file is as below:
urlpatterns = [
url(r'^', include('app1.urls')),
]
The urls.py file inside app1 is:
from django.conf.urls import url
from . import views
app_name = 'app1'
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^details/$', views.details, name='details'),
]
The views.py for app1 is as below:
from django.shortcuts import render, redirect
from django.utils.timezone import now
import datetime
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
def home(request):
if request.method == 'POST':
print("redirected from home..................")
url = reverse('details')
return HttpResponseRedirect(url)
# return redirect('app1:details')
# return redirect('/details/')
# return redirect('details')
print("Not redirected..................")
return render(request, "app1/index.html", {})
def details(request):
print("Redirect OK inside details")
today = datetime.date.today()
return render(request, "app1/details.html", {
'today': today,
'now': now(),
'email_text': request.POST.get('email_item', 'bla bla'),
})
I tried all the options in the home view with the commented code like using both HttpResponseRedirect and redirect but not able to redirect to the details view.
I get the error:
django.urls.exceptions.NoReverseMatch: Reverse for 'details' with
arguments '()' and keyword arguments '{'request': <HttpRequest>}' not found. 0 pattern(s) tried: []
Any suggestions would help:
Upvotes: 0
Views: 2303
Reputation: 2444
I'm sure you found a solution long ago, but I've struggled with this problem before and I came up with a simple solution that doesn't require you to create a view that exists solely to redirect you to another view. Hopefully it helps some people out who need this question answered still. In general, it goes like this:
from django.shortcuts import redirect
urlpatterns = [
url(r'^$', lambda request: redirect('my_redirect_url_name')),
url(r'^my_redirect_url/$', views.redirect_view, name='my_redirect_url_name'))
]
I'm not sure why, but this does not work if you only pass redirect()
; it must be contained within a function such as a lambda
function.
If you want to do something as simple as redirect them to the login page you can use the login_required
decorator or another a custom login lambda function:
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
urlpatterns = [
url(
r'^$',
login_required(lambda request: redirect('my_redirect_url_name'),
redirect_field_name='my_login_url_name')
),
# this custom redirect function will behave like login_required()
url(
r'^$',
lambda request: redirect('my_redirect_url_name') if request.user and \
request.user.is_authenticated() else redirect('my_login_url_name')
),
url(r'^my_redirect_url/$', views.redirect_view, name='my_redirect_url_name')),
url(r'^my_login_url/$', views.login_view, name='my_login_url_name'))
]
Specifically in answer to your question, I think this will give the redirect you want. This in urls
:
from django.shortcuts import redirect
urlpatterns = [
url(
r'^$',
lambda request: redirect('index') if request.method == 'POST' else \
redirect('details'),
name='home'
),
url(r'^details/$', views.details, name='details'),
url(r'^index/$', views.index, name='index'),
]
With this added to views
:
def index(request):
return render(request, "app1/index.html", {})
Just FYI, I have not tested this with a redirect using if request.method == 'POST'
, but I think it will work.
Upvotes: 2
Reputation: 296
Note the working example within your own code.
By specifying the app name you need to use namespacing with reverse.
reverse('details')
should read
reverse('app1:details')
See the documentation over here: https://docs.djangoproject.com/en/1.10/ref/urlresolvers/
Upvotes: 1