django 偶尔会抛出一个 NoReverseMatch
Posted
技术标签:
【中文标题】django 偶尔会抛出一个 NoReverseMatch【英文标题】:django occasionally throwing a NoReverseMatch 【发布时间】:2015-08-18 08:48:35 【问题描述】:我在 django 模板渲染中偶尔出现错误;我有时会在以下 URL 上获得 NoReverseMatch:
url(r'^student-agreement/(?P<code>[\w:-]+)$',
StudentAgreementView.as_view(),
name='student-agreement'),
code
参数是通过在对象 ID 上调用 signing.dumps()
创建的,这会创建一个字符串,例如 'MjExMg:1Z0H6s:1H19SjhO2CCAlAUgkiYLvyYLSzI'
- 据我所知,这应该与提供的正则表达式匹配。但是,尝试如下测试:
for i in range(20)
print reverse('student-agreement', kwargs='code':signing.dumps(i))
会很快抛出 NoReverseMatch。
这是一个示例 Traceback:
Traceback (most recent call last):
File "/home/vagrant/.virtualenvs/sis_esv_repo/local/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2883, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-58-f02835044aa6>", line 2, in <module>
print reverse('student-agreement', kwargs='code':signing.dumps(i))
File "/home/vagrant/.virtualenvs/sis_esv_repo/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 551, in reverse
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "/home/vagrant/.virtualenvs/sis_esv_repo/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 468, in _reverse_with_prefix
(lookup_view_s, args, kwargs, len(patterns), patterns))
NoReverseMatch: Reverse for 'student-agreement' with arguments '()' and keyword arguments ''code': 'Mg:1Z0H9L:ltHc7mAAteN7jBHRBIuT-Zbzt18'' not found. 1 pattern(s) tried: ['school/student-agreement/(?P<code>[\\w:-_]+)$']
【问题讨论】:
嘿,您发布的正则表达式(?P<code>[\w:-]+)$
与回溯中的正则表达式 (?P<code>[\\w:-_]+)$
不同
@fasouto - 我只能猜测,当在回溯中打印出来时,python 使用正常的字符串表示,而不是原始模式 docs.python.org/2/library/re.html#raw-string-notation - 而且,它在某些时候有效,而不是其他时间。
@fasouto - 我的错误 - 我没有注意到那里的额外下划线,只是反斜杠。所以我正在运行的测试正在使用一个调试会话,那里仍然有我的旧正则表达式[\w:-_]
。在试图找出问题所在时,我意识到下划线不是必需的,因为\w
包含下划线。重新启动调试会话后,我再也不能让它以这种方式失败了。这很奇怪,因为我预计正则表达式 [\w:-]
和 [\w:-_]
是相同的。
哦该死的; [:-_]
获取从 :
到 _
的所有字符 - 如果在正则表达式字符集中使用连字符,它必须是最后一项。所以[\w:_-]
可以,但[\w:-_]
不行
【参考方案1】:
原来我在运行测试时使用的正则表达式与我在问题中发布的略有不同 - 我没有重新加载我的实例,它使用的是我一直使用的旧正则表达式:(?P<code>[\w:-_]+)
.正确的正则表达式是 (?P<code>[\w:-]+)
- :-_
使正则表达式匹配从 : 到 _ 的范围,但不包括连字符本身。正确的正则表达式在集合末尾有连字符,因此它被视为连字符。由于\w
包含下划线,因此下划线不是必需的,但(?P<code>[\w:_-]+)
也是正确的正则表达式。
感谢@fasouto 为我指明了正确的方向!
【讨论】:
【参考方案2】:输出也会产生_
字符。
【讨论】:
我最初在正则表达式中有 _ 但它也有同样的问题。经过一番调查,我在 python 文档中发现: \w 当未指定 LOCALE 和 UNICODE 标志时,匹配任何字母数字字符和下划线;这等价于集合 [a-zA-Z0-9_]。使用 LOCALE,它将匹配集合 [0-9_] 加上当前语言环境中定义为字母数字的任何字符。如果设置了 UNICODE,这将匹配字符 [0-9_] 加上 Unicode 字符属性数据库中分类为字母数字的任何内容。以上是关于django 偶尔会抛出一个 NoReverseMatch的主要内容,如果未能解决你的问题,请参考以下文章
在 Django 1.7 迁移中调用 loaddata 会抛出“‘字段列表’中的未知列‘[字段]’”