【问题标题】:understading django.shortcuts.reverse, part 2理解 django.shortcuts.reverse,第 2 部分
【发布时间】:2012-08-16 11:09:05
【问题描述】:

Understanding django.shortcuts.redirect 中,我发起了一个关于reverseredirect_to 的帖子。

当第一个参数是字符串时,我仍然无法理解reverse 的工作原理。我多次阅读https://docs.djangoproject.com/en/1.4/topics/http/shortcuts/#django.shortcuts.redirectreverse 的相应部分。但我仍然收到NoReverseMatch 异常。

在我的ROOT_URLCONF 我有

urlpatterns = patterns('',
    url(r'^$', redirect_to, {'url': '/monitor/'}),
    url(r'^monitor/', include('monitor.urls')),
)

monitor.urls我有

urlpatterns = patterns('monitor.views',
    (r'^$', 'index'),
    (r'^list', 'listall'),
)

monitor.urls 中,我已经为indexlistall 这两个函数定义了代码。在listall 我添加了以下几行:

def listall(request):
    <more code goes here>
    print "reversing 1 index: %s " % reverse(index)
    print "reversing 2 index: %s " % reverse('index')
    render_to_response("monitor/list.htmld", params)

如果我访问 localhost:3000/monitor/list 那么我可以看到

reversing 1 index: /monitor/ 

仅此而已,第二个reverse 引发了异常。为什么?我错过了什么?

我追踪到 djangos 代码 django.core.urlresolvers.callabledjango.core.urlresolvers.get_mod_funcget_mod_func 似乎期待像“a.b”这样的东西,这就是为什么在callable 中,第一行为func_name 返回了“索引”,但为mod_name 返回了一个空字符串。我将第二行更改为

    print "reversing 2 index: %s " % reverse('monitor.views.index')

它按预期工作。那么,为什么我需要使用完整的模块和函数名称(当我使用字符串时)调用 reverse 而文档不需要呢?我错过了什么?

谢谢

【问题讨论】:

  • 据我所知,reverse 希望能够通过name 参数或被调用函数的完全限定路径找到URL 模式。
  • monitor.urls 中使用url() 作为urlpatterns 的一项(与ROOT_URLCONF 相同) - url() 具有可选的name 属性,这是可以用作字符串的字符串“反向”参数
  • @yedpodtrzitko:我不能完全理解你的意思:(

标签: django


【解决方案1】:

我不确定你挂断了文档的哪一部分,但reverse 的第一个参数是一些获取视图的识别方法:它可以是 urlpattern 名称,也可以是完整的虚线路径到视图,或视图本身

因此,根据您的示例,第一种方法已失效,因为您没有为 urlpattern 定义名称。您的第一次尝试,reverse(index) 成功了,因为您确实将视图传递给了它。您的第二次尝试 reverse('index') 不起作用,因为它需要完整的导入上下文,即 'monitor.views.index'。两者的区别在于,当它是一个字符串时,Django 必须解释该字符串来为视图创建一个导入——而 'index' 信息不足以确定导入路径。

但是,如果您打算反转它们,最好只命名您的视图,并且您还应该命名您包含的 urlpatterns,这样两个不同的应用程序就不会最终发生冲突。所以在项目级的urls.py中:

urlpatterns = patterns('',
    url(r'^$', redirect_to, {'url': '/monitor/'}),
    url(r'^monitor/', include('monitor.urls', namespace='monitor', app_name='monitor')),
)

然后,在monitor/urls.py中:

urlpatterns = patterns('monitor.views',
    (r'^$', 'index', name='index'),
    (r'^list', 'listall', name='listall'),
)

那么,反转就像reverse('monitor:index') 一样简单。

【讨论】:

    【解决方案2】:

    你应该做类似的事情

    reverse('monitor:index')
    

    ROOT_URLCONF我有

    urlpatterns = patterns('',
       (r'^$', redirect_to, {'url': '/monitor/'}),
       (r'^monitor/', include('monitor.urls'),namespace='monitor'),
    )
    

    monitor.url.py:

    urlpatterns = patterns('monitor.views',
       url(r'^$', 'index',name='index'),
    )
    

    更多详情请查看https://docs.djangoproject.com/en/1.4/topics/http/urls/#django.core.urlresolvers.reverse

    【讨论】:

    • (r'^$', 'index',name='index'), 生成和语法错误:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多