在Django中反转命名空间的URL:同一个应用程序的多个实例 [英] Reversing namespaced URLs in Django: multiple instances of the same app

查看:239
本文介绍了在Django中反转命名空间的URL:同一个应用程序的多个实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  urlpatterns = patterns('',
(r'^ instance1 /',include('myapp.urls',namespace ='instance1')),
(r' ^ instance2 /',include('myapp.urls',namespace ='instance2')),

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

  return HttpResponseRedirect(reverse('view_name '))

或在我的一个模板中这样的东西:

 < a href ={%url view_name%}>链接文本< / a> 

...其中 view_name 是名称包含在 myapp.urls 中的网址格式。由于我使用命名空间,这会引发一个错误:没有视图名为 view_name 。相反,我必须告诉它 instance1:view_name instance2:view_name 。但是,动态地这样做会让我失望。



我做了一些看,看起来像 current_app 参数,传递给上下文 RequestContext ,旨在帮助这一点,但是并不清楚如何动态地传递 right 应用程序名称为 current_app 。那么什么是正确的方式告诉Django哪个命名空间使用?



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

解决方案

不是一个很好的解决方案,但由于您使用相同的文本作为命名空间和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']


当然,如果你这样做,你一定要为这个应用程序使用请求路径/命名空间


I've been working with Django for a while now (currently on version 1.2), but just recently started working on an app that needs to support multiple instances. E.g., the project urls.py file will include it twice, under two different namespaces, like this:

urlpatterns = patterns('',
    (r'^instance1/', include('myapp.urls', namespace='instance1')),
    (r'^instance2/', include('myapp.urls', namespace='instance2')),
)

I was going along fine, until I realized I needed to figure out what to do about all the internal calls to reverse() (or the template calls to the {% url %} filter). For instance, let's say I'm doing something like the following in one of my views:

return HttpResponseRedirect(reverse('view_name'))

or something like this in one of my templates:

<a href="{% url view_name %}">link text</a>

...where view_name is the name of a URL pattern contained in myapp.urls. Since I'm using namespaces, this will raise an error: there is no view called view_name. Rather, I have to tell it either instance1:view_name or instance2:view_name. But doing this dynamically is stumping me.

I did some looking and it looks like the current_app argument, passed to either Context or RequestContext, was designed to help with this, but it's not clear at all how to dynamically pass the right application name to current_app. So what's the right way to tell Django which namespace to use?

EDIT: My use case is to use a single installation of the app multiple times. That is, it only exists on disk once, but gets included multiple times in the project's root urls.py (each time under a different namespace, as in my example above). With this in mind, is there any good way to keep track of which namespace a view/template is being called from, and make any use of reverse() or {% url %} stick within the same namespace? I know Django 1.3 will provide some extra features that could help with this (namely, the new and improved resolve()), but surely there's a good way to do this now...

解决方案

Not a very nice solution, but since you use the same text for your namespace and initial part of the URL path, you can extract that element from request.path (request.path.split('/')[1]) and set that as current_app in the request context, or just use it as the namespace in views.

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

You could do that e.g. in a context processor (if you want to use the namespace in a template).

For views you could write a decorator that feeds your function an extra kwarg "namespace" and use it as:

@feed_namespace
def view1(request, *args, **kwargs):
    ns = kwargs['namespace']

or just write a reverse_namespaced function with an extra param (the request) where the function gets the namespace from, and use it instead of reverse.

Of course if you do this you will always have to use a request path/namespace for this app

这篇关于在Django中反转命名空间的URL:同一个应用程序的多个实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆