当我尝试将两个参数从一个视图传递到另一个视图时,我收到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,})/$']
我在项目中的不同应用程序中运行相同的代码模式,并且运行时没有错误。谁能看到我做错了什么?
答案 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,}
更具可读性,但它们的意思相同。)