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

Nik*_*ike 8 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') ),)
Run Code Online (Sandbox Code Playgroud)

和照片/ urls.py:

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

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

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

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

谢谢,尼克

ste*_*lis 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') ),
)
Run Code Online (Sandbox Code Playgroud)

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

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

r = resolve(request.path)
r.app_name  # the app name
r.namespace # the the currently active instance
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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

{% url webui_photos:album-create %} {# returns the url for whatever app is current #}
{% url car-photos:album-create %}
{% url profile-photos:album-create %}
Run Code Online (Sandbox Code Playgroud)

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

reverse('webui_photos:album-create', current_app=resolve(self.request.path).namespace))
Run Code Online (Sandbox Code Playgroud)


Nik*_*ike -3

在探索这个主题几天后,我发现多次挂载 django app 并不自然。

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

因此,我决定将重复的功能移至自定义标签,并为我的应用程序的每次使用复制模板。我希望使用自定义标签和扩展功能可以帮助我遵循 DRY 原则。