如何在多部署可重用的Django应用程序中获取current_app以使用reverse?

时间:2010-01-08 19:44:14

标签: python django django-urls

我正在编写可重用的应用程序。我想多次部署它。

这是urls.py:

urlpatterns = patterns('',
(r'^carphotos/', include('webui.photos.urls', app_name='car-photos') ),
(r'^userphotos/', include('webui.photos.urls',  app_name='profile-photos') ),)

和photos / urls.py:

urlpatterns = patterns('webui.photos.views',
url(r'^$', album_list, name="album-list" )
url(r'^newalbum/$', album_page, {'create': True}, name="album-create"),)

在album_list视图中,我想显示用于创建新相册album_page的网址。

我发现我必须使用反向函数的参数current_app来获取正确的URL。

但是如何获得这个current_app? 我认为答案很简单。但我在django文档中找不到它。

谢谢,尼克

4 个答案:

答案 0 :(得分:11)

我知道这是一个非常古老的问题......但我认为我找到了一个解决方案:

正如Will Hardy建议你必须为两个实例保持app_name相同(或根本不定义它,它将默认为包含的URL所在的应用程序)。为每个应用实例定义一个单独的命名空间:

urlpatterns = patterns('',
    (r'^carphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='car-photos') ),
    (r'^userphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='profile-photos') ),
)

现在,在视图中设置当前活动的应用程序实例(命名空间)有点棘手。这意味着您必须找出哪个应用实例处于活动状态并将其传递给RequestContext

要查找当前有效的应用,可以使用django.core.urlresolvers.resolve

r = resolve(request.path)
r.app_name  # the app name
r.namespace # the the currently active instance

因此,您必须相应地更新您的视图(假设使用基于类的视图):

from django.core.urlresolvers import resolve
from django.views.generic import TemplateView


class AlbumCreateView(TemplateView):
    template_name = 'path/to/my/template.html'

    def render_to_response(self, context, **response_kwargs):
        response_kwargs['current_app'] = resolve(self.request.path).namespace
        return super(AlbumPageView, self).render_to_response(context, **response_kwargs)

现在,url标记将自动反转到正确的命名空间,并且仍然允许在需要时反转到特定的应用程序命名空间:

{% url webui_photos:album-create %} {# returns the url for whatever app is current #}
{% url car-photos:album-create %}
{% url profile-photos:album-create %}

要在视图中反转网址,必须手动传递当前的应用实例:

reverse('webui_photos:album-create', current_app=resolve(self.request.path).namespace))

答案 1 :(得分:1)

在您的网址中,即使它是相同的应用,您也会有不同的app_name。将app_name设置为相同的内容,并为每个实例唯一设置namespace。例如

urlpatterns = patterns('',
(r'^carphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='car-photos') ),
(r'^userphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='profile-photos') ),)

然后在使用reverse时提供current_app参数。请参阅http://docs.djangoproject.com/en/dev/topics/http/urls/#reversehttp://docs.djangoproject.com/en/dev/topics/http/urls/#url-namespaces

重新阅读你的问题后

[编辑]:

如果您使用current_app标记,则无需提供{% url %}参数。据我所知,它会自动访问一个名为current_app的模板变量,该模板变量会根据匹配的网址自动设置。

答案 2 :(得分:-3)

经过几天探讨​​这个话题后,我发现不止一次安装django app是不自然的。

有可插拔应用程序模式的实现: http://github.com/nowells/django-pluggables。 对我来说这看起来太棘手了。

所以我决定将重复的功能转移到我的应用的每次使用的自定义标签和重复模板。我希望使用自定义标签和扩展功能帮助我遵循DRY原则。

答案 3 :(得分:-4)

我相信这是sites框架的用途。