Django 1.10:重定向到另一个视图或网址无法正常工作。 django.urls.exceptions.NoReverseMatch

时间:2016-09-11 16:58:05

标签: django redirect django-views

在Django 1.10中,我通过url或viewname重定向到其他视图无效。

主要的urls.py文件如下:

urlpatterns = [
    url(r'^', include('app1.urls')),
]

app1中的urls.py文件是:

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'),

]

app1的views.py如下:

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'),
        })

我使用注释代码尝试了主视图中的所有选项,例如同时使用HttpResponseRedirect和重定向,但无法重定向到详细信息视图。

我收到错误:

    django.urls.exceptions.NoReverseMatch: Reverse for 'details' with
 arguments '()' and keyword arguments '{'request': <HttpRequest>}' not found. 0 pattern(s) tried: []

任何建议都会有所帮助:

2 个答案:

答案 0 :(得分:2)

我很确定你很久以前就找到了解决方案,但之前我一直在努力解决这个问题,我想出了一个简单的解决方案,它不需要你创建一个仅用于将你重定向到另一个视图的视图。希望它可以帮助一些需要这个问题的人。一般来说,它是这样的:

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'))
]

我不知道为什么,但如果你只通过redirect(),这不起作用;它必须包含在诸如lambda函数之类的函数中。

如果你想做一些简单的事情,比如将它们重定向到登录页面,你可以使用login_required装饰器或另一个自定义登录lambda函数:

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'))
]

特别是在回答您的问题时,我认为这会给您想要的重定向。这在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'),
]

将此添加到views

def index(request):
    return render(request, "app1/index.html", {})

仅供参考,我没有使用if request.method == 'POST'进行重定向测试,但我认为它会有效。

答案 1 :(得分:1)

请注意您自己的代码中的工作示例。

通过指定应用名称,您需要使用反向命名空间。

reverse('details')

应该阅读

reverse('app1:details')

请参阅此处的文档: https://docs.djangoproject.com/en/1.10/ref/urlresolvers/