模板操作 url 中的 NoReverseMatch

Posted

技术标签:

【中文标题】模板操作 url 中的 NoReverseMatch【英文标题】:NoReverseMatch within a template action url 【发布时间】:2015-01-03 19:11:38 【问题描述】:

我的主 urlconf 中有这个 URL:

url(r'^confirm-invite/(?P<token>[\w-]+)/$', confirm_invite, name="confirm_invite_page"),

这是它所连接的(WIP 版本)视图:

def confirm_invite(req, token):
    template_name = 'invites/confirm_invite.html'

    if req.method == 'POST':
        form = ActivationForm(req.POST)
        if form.is_valid():

            try:
                auth_user = authenticate(username=user.username, password=form.cleaned_data['activation_code'])
            except:
                return HttpResponse('didnt authenticate')
            if auth_user is None:
                return HttpResponse('auth_user is none')
            login(req, auth_user)
            return HttpResponse('you activated your account')
        else:
            return HttpResponse('form error foo')
    else:
        invite = get_object_or_404(Invite, token=token)
        user = invite.user
        if user.is_active == True:
            return HttpResponse('user is already active')
        else:
            form = ActivationForm()
            return render(req, template_name, 'form': form)

这是 HTML 的 sn-p:

<form action="% url 'confirm_invite_page' token %" method="post">% csrf_token %
        form.as_p
        <input type="submit" value="Activate">
</form>

由于某种原因,HTML 中的反向 URL % url 'confirm_invite_page' token % 抛出了匹配问题

这是完整的回溯:

Traceback:
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/nir/nirla/nirla/apps/invites/views.py" in confirm_invite
  78.               return render(req, template_name, 'form': form)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/shortcuts/__init__.py" in render
  53.     return HttpResponse(loader.render_to_string(*args, **kwargs),
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/loader.py" in render_to_string
  169.         return t.render(context_instance)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/base.py" in render
  140.             return self._render(context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/base.py" in _render
  134.         return self.nodelist.render(context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/base.py" in render
  840.                 bit = self.render_node(node, context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/debug.py" in render_node
  78.             return node.render(context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/loader_tags.py" in render
  123.         return compiled_parent._render(context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/base.py" in _render
  134.         return self.nodelist.render(context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/base.py" in render
  840.                 bit = self.render_node(node, context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/debug.py" in render_node
  78.             return node.render(context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/loader_tags.py" in render
  62.             result = block.nodelist.render(context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/base.py" in render
  840.                 bit = self.render_node(node, context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/debug.py" in render_node
  78.             return node.render(context)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/defaulttags.py" in render
  447.                         six.reraise(*exc_info)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/template/defaulttags.py" in render
  433.             url = reverse(view_name, args=args, kwargs=kwargs, current_app=context.current_app)
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/core/urlresolvers.py" in reverse
  532.     return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "/Users/nir/nirla/venv/lib/python2.7/site-packages/django/core/urlresolvers.py" in _reverse_with_prefix
  452.                              (lookup_view_s, args, kwargs, len(patterns), patterns))

Exception Type: NoReverseMatch at /confirm-invite/6f0ce05c8404470bb996f20c8271e363/
Exception Value: Reverse for 'confirm_invite_page' with arguments '('',)' and keyword arguments '' not found. 1 pattern(s) tried: ['confirm-invite/(?P<token>[\\w-]+)/$']

考虑到文档,我认为这是正确设置的,匹配有什么问题?

【问题讨论】:

【参考方案1】:

你需要把最后一行改成

return render(req, template_name, 'form': form, 'token': token)

否则,模板没有这个变量。

【讨论】:

【参考方案2】:

“令牌”没有吗?它似乎基于堆栈跟踪。您需要确保该变量设置为某个值,否则 url 模板标签将失败,因为它将查找其中 url 中没有参数的匹配项,即使您的显然是这样。

【讨论】:

令牌“无”是什么意思?令牌被传递到呈现页面的 URL。我想我可以在视图中进行分配,但这似乎没有意义。你能澄清一下吗? 在你的模板中,是不是没有定义上下文变量token?您似乎没有将其传递到视图中。 url 模板标签要求您将所有必要的 args/kwargs 传递给您的 url。一个简单的测试,看看这是否是问题是用“1”或其他一些微不足道的替换“token”。所以你可以试试:% url 'confirm_invite_page' '1' %。

以上是关于模板操作 url 中的 NoReverseMatch的主要内容,如果未能解决你的问题,请参考以下文章

Django 模板中的字符串操作

液体模板过滤器中的日期数学/操作

如何在模板中删除 django URL 中的尾随斜杠?

webapp2 - 如何反转模板中的URL?

CSS 文件中的 Django 媒体 URL

Django04-模板系统Template