如何在 Django 命名空间可重用应用程序中进行反向 URL 搜索

Posted

技术标签:

【中文标题】如何在 Django 命名空间可重用应用程序中进行反向 URL 搜索【英文标题】:How to do reverse URL search in Django namespaced reusable application 【发布时间】:2011-04-04 11:35:10 【问题描述】:

考虑我包含命名空间的可重用应用程序:

urlpatterns = patterns('',
    # ella urls
    url('^ella/', include('ella.core.urls', namespace="ella")),
)

现在,Ella 应用程序有这样的网址:

urlpatterns = patterns( '',
    url( r'^(?P<category>[a-z0-9-/]+)/$', category_detail, name="category_detail" ),
    # object detail
    url( r'^(?P<category>[a-z0-9-/]+)/(?P<year>\d4)/(?P<month>\d1,2)/(?P<day>\d1,2)/(?P<content_type>[a-z0-9-]+)/(?P<slug>[a-z0-9-]+)/$',
        object_detail, name="object_detail" )
)

现在,调用 % url ella:category_detail category="cat" % 可以正常工作。但是,当对象尝试生成指向其详细信息的链接时,它会调用

from django.core.urlresolvers import reverse
url = reverse('object_detail', kwargs='required' : 'params')

这是行不通的,除非重写为

from django.core.urlresolvers import reverse
url = reverse('ella:object_detail', kwargs='required' : 'params')

所以,如果我理解正确,将可重用应用程序包含在命名空间中会破坏给定应用程序内的所有内部 reverse()

这是真的吗?我错过了什么?有什么办法吗?

【问题讨论】:

【参考方案1】:

至少在 Django 1.8 中你可以这样写:

url = reverse('%s:object_detail' % request.resolver_match.namespace, kwargs='required' : 'params')

request.resolver_match.namespace 是一个字符串,包含当前正在运行的视图的命名空间。

【讨论】:

【参考方案2】:

可以通过两种方式指定 URL 命名空间。

首先,您可以在构建 URL 模式时将应用程序和实例命名空间作为参数提供给 include()。例如:

(r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')),

这是来自http://docs.djangoproject.com/en/dev/topics/http/urls/#defining-url-namespaces。

尝试将include('ella.core.urls', namespace="ella") 更改为include('ella.core.urls', namespace="ella", app_name="ella")。我不是 100% 这会奏效,但值得一试。

【讨论】:

【参考方案3】:

由于您有命名空间 url 配置,您需要提及 namespace:view-name 模式以便正确地反转它(尤其是从视图中)。

但是,如果您想避免这种情况,您也可以将 namespace/appname 作为 current_app 参数传递。 当您在模板中时,有多种方法可以指定 current_app。但是如果你在视图中,你需要像你一样进行硬编码,或者传递给 current_app 参数

url = reverse('object_detail', 
              kwargs='foo':'bar', 
              current_app=app_name_or_name_space)

参考:http://docs.djangoproject.com/en/dev/topics/http/urls/#reverse

【讨论】:

我认为真正的问题是:有没有办法将第三方可重用应用程序包含在 URL 命名空间中,而无需在可重用应用程序内重写对 reverse() 函数的所有调用。 是的,没错。 current_app 与前缀相同的硬代码:...但感谢您的技巧。 同意。但是,如何获取当前的应用名称?有没有这样的,否则真正可插拔的应用程序是如何工作的。

以上是关于如何在 Django 命名空间可重用应用程序中进行反向 URL 搜索的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 中重用可重用的应用程序

来自不同命名空间的同名对象的可重用函数代码?

如何为 django 可重用应用程序启动测试?

Django(命名空间)

如何跨命名空间和平台伪造库(GDI 到 Xamarin.Forms),例如重用 Color 结构

PHP之命名空间