在Django中反转命名空间的URL:同一个应用程序的多个实例

mjj*_*son 12 django namespaces

我一直在使用Django一段时间(目前在1.2版本上),但最近才开始研究需要支持多个实例的应用程序.例如,项目urls.py文件将在两个不同的命名空间下包含两次,如下所示:

urlpatterns = patterns('',
    (r'^instance1/', include('myapp.urls', namespace='instance1')),
    (r'^instance2/', include('myapp.urls', namespace='instance2')),
)
Run Code Online (Sandbox Code Playgroud)

我一直很顺利,直到我意识到我需要弄清楚如何处理所有内部调用reverse()(或模板调用{% url %}过滤器).例如,假设我在我的一个观点中做了类似下面的事情:

return HttpResponseRedirect(reverse('view_name'))
Run Code Online (Sandbox Code Playgroud)

或者我的一个模板中的类似内容:

<a href="{% url view_name %}">link text</a>
Run Code Online (Sandbox Code Playgroud)

... view_name包含在哪里的URL模式的名称myapp.urls.由于我使用名称空间,这将引发错误:没有调用视图view_name.相反,我必须告诉它instance1:view_name或者instance2:view_name.但动态地这样做是让我感到难过.

我做了一些看起来,它看起来像是current_app传递给或者,Context或者RequestContext,旨在帮助这个,但它并不清楚如何动态传递正确的应用程序名称current_app.那么告诉Django使用哪个命名空间的正确方法是什么?

编辑:我的用例是多次使用应用程序的单个安装.也就是说,它只存在于磁盘上一次,但在项目的根目录中被多次包含urls.py(每次都在不同的命名空间下,如上例所示).考虑到这一点,有没有什么好方法可以跟踪调用视图/模板的命名空间,并在同一命名空间中使用reverse(){% url %}粘贴?我知道Django 1.3将提供一些额外的功能,可以帮助解决这个问题(即新的和改进的resolve()),但是现在肯定有一个很好的方法可以做到这一点......

Car*_*bés 3

这不是一个很好的解决方案,但由于您对命名空间和 URL 路径的初始部分使用相同的文本,因此您可以从request.path( request.path.split('/')[1]) 中提取该元素并将其设置current_app为请求上下文中的内容,或者仅将其用作视图中的命名空间。

http://docs.djangoproject.com/en/dev/topics/http/urls/#url-namespaces第2点。

您可以在上下文处理器中执行此操作(如果您想在模板中使用名称空间)。

对于视图,您可以编写一个装饰器,为您的函数提供额外的 kwarg“命名空间”,并将其用作:

@feed_namespace
def view1(request, *args, **kwargs):
    ns = kwargs['namespace']
Run Code Online (Sandbox Code Playgroud)

或者只编写一个带有额外参数(请求)的reverse_namespaced函数,该函数从中获取命名空间,并使用它而不是rev​​erse。

当然,如果您这样做,您将始终必须使用此应用程序的请求路径/命名空间