无法修复Django NoReverseMatch错误

时间:2017-07-18 19:50:49

标签: django django-views

当我尝试将两个参数从一个视图传递到另一个视图时,我收到NoReverseMatch错误。这是传递参数的视图:

# promotion/views.py
def enter_promo_code(request, template):
    if request.method == "POST":
        form = PromotionCodeForm(request.POST)
        if form.is_valid():
            message_text, expiry_date = process_valid_promo_code(request.user, form.cleaned_data['promo_code'])
            return HttpResponseRedirect(reverse('welcome-page-promo', \
                    kwargs={'message_text': message_text, 'expiry_date': expiry_date}))
    else:
        form = PromotionCodeForm(label_suffix="")
    context = {'form': form}
    return render(request, template, context)

这是接收视图。请注意,两个输入参数是可选的。 urlpatterns显示可以使用或不使用参数调用此视图。

# home/views.py
def welcome_page(request, template, message_text=None, expiry_date=None):
    account = Account.objects.get(pk=request.user.id)
    context = {'uid': request.user.id, 'account_type': account.type.account_type_cd, 'message_text': message_text, 'expiry_date': expiry_date}
    return render(request, template, context)

以下是接收视图的urlpatterns:

# home/urls.py
url(r'^welcome/$',
    'home.views.welcome_page',
    {'template': 'welcome_page.html'},
    name='welcome-page'),

url(r'^welcome/(?P<message_text>\w{1,})/(?P<expiry_date>\w{1,})/$',
    'home.views.welcome_page',
    {'template': 'welcome_page.html'},
    name='welcome-page-promo'),

执行促销视图时,执行返回HttpResponseRedirect命令时出现此错误:

NoReverseMatch at /promotion/code/
Reverse for 'welcome-page-promo' with arguments '()' and keyword arguments '{'message_text': u'Your promotion code was approved!  You will receive a one-year free trial membership which expires on ', 'expiry_date': 'Jul. 18, 2018'}' not found. 1 pattern(s) tried: ['welcome/(?P<message_text>\\w{1,})/(?P<expiry_date>\\w{1,})/$']

我在项目中的不同应用程序中运行相同的代码模式,并且运行时没有错误。谁能看到我做错了什么?

1 个答案:

答案 0 :(得分:0)

这里有两个问题,一个是设计问题,一个是实现问题。

设计问题是您的网址中可能不应该有这么长的文字。我相信Django会处理为你逃脱的争论,但它仍然不是最容易使用的模式。在我看来,你的message_text参数可能是静态的,或至少从少数可能性中选择。您很可能应该将其记录在模板中,为其创建模型并传递ID,或者沿着这些线传递。在URI中传递日期并没有什么问题,虽然我更喜欢2018-07-18之类的更简单的格式而不是Jul. 18, 2018,但如果它确实是一个到期日期,您可能希望拥有一个成员资格模型并将其设置为那里有一个属性,然后查看它的欢迎页面视图。

将它放在一边并查看您的实现问题 - 您的视图regexp仅匹配\w类中的一个或多个字符,其定义为:

  

如果未指定LOCALE和UNICODE标志,则匹配任何字母数字字符和下划线;这相当于集合[a-zA-Z0-9_]。对于LOCALE,它将匹配集[0-9_]以及任何字符被定义为当前语言环境的字母数字。如果设置了UNICODE,这将匹配字符[0-9_]以及Unicode字符属性数据库中分类为字母数字的字符。

但是,您的args包含!和空格等字符。使用符合所需参数的正则表达式 - [^/]+是一个,如果您想要原谅。 (+在我看来比{1,}更具可读性,但它们的意思相同。)