未找到带参数'()'和关键词参数'{}'的'*'反向查找

63 投票
7 回答
153352 浏览
提问于 2025-04-15 16:39

在渲染的时候遇到了一个错误:

找不到名为 'products.views.'filter_by_led' 的反向路径,传入的参数是 '()',关键字参数是 '{}'。

我在命令行里成功导入了 products.views.filter_by_led,而且运行正常,所以路径应该是对的。

这是 urls.py 文件:

(r'^led-tv/$', filter_by_led ),

错误就是在这里产生的:

href="{% url products.views.filter_by_led %}">

我不明白,因为从同一个文件里这个是可以正常工作的:

{% url products.views.lcd_screen_size screen_size=50 %}

这是函数的定义:

def filter_by_led(request):

我不明白为什么 Django 会认为找不到这个函数的反向路径。

我删除了所有的 *.pyc 文件,并重启了 Apache。

我到底哪里做错了呢?

7 个回答

12

你需要在视图名称周围加上单引号

{% url 'viewname' %}

而不是

{% url viewname %}
37

在调试这些问题时,使用Shell调用reverse非常有效,但有两个重要的条件:

  • 必须提供与视图所需参数匹配的参数,
  • 这些参数必须符合正则表达式模式。

是的,这很合理。但也很让人困惑,因为reverse只会抛出异常,而不会给你更多的提示。

一个URL模式的例子:

url(r'^cookies/(?P<hostname>[^/]+)/(?P<url_id>\d+)/$', 'register_site.views.show_cookies', name='show_cookies'),

然后在Shell中发生了什么:

>>> from register_site.views import show_cookies
>>> reverse(show_cookies)
NoReverseMatch: Reverse for 'register_site.views.show_cookies' with arguments '()' and keyword arguments '{}' not found.

这不工作,因为我没有提供任何参数。

>>> reverse('show_cookies', kwargs={'url_id':123,'hostname': 'aaa'})
'/cookies/aaa/123'

现在它工作了,但……

>>> reverse('show_cookies', kwargs={'url_id':'x','hostname': 'www.dupa.com'})
NoReverseMatch: Reverse for 'show_cookies' with arguments '()' and keyword arguments '{'url_id': 'x', 'hostname': 'www.dupa.com'}' not found.

现在它不工作了,因为url_id没有匹配正则表达式(期望是数字,但提供的是字符串)。

你可以用reverse来处理位置参数和关键字参数。语法是:

reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None)

说到url模板标签,有件有趣的事。Django的文档给出了使用带引号的视图名称的例子:

{% url 'news.views.year_archive' yearvar %}

所以我在我的HTML模板中以类似的方式使用了它:

{% url 'show_cookies' hostname=u.hostname url_id=u.pk %}

但这对我来说不管用。不过异常信息给了我一个提示,可能哪里出了问题——注意视图名称周围的双单引号:

Reverse for ''show_cookies'' with arguments...

当我去掉引号时,它开始工作了:

{% url show_cookies hostname=u.hostname url_id=u.pk %}

确实让人困惑。

57

我能想到的有三件事:

  1. 可以使用命名的URL,这样更稳妥,也更容易维护。
  2. 在命令行中试试使用django.core.urlresolvers.reverse,这样可能会得到更好的错误信息。

    >>> from django.core.urlresolvers import reverse
    >>> reverse('products.views.filter_by_led')
    
  3. 检查一下是否有多个URL指向同一个视图。

撰写回答