Как получить current_app для использования с reverse в многоразовых многоразовых приложениях Django? - PullRequest
8 голосов
/ 08 января 2010

Пишу многоразовое приложение. И я хочу развернуть его несколько раз.

Вот urls.py:

urlpatterns = patterns('',
(r'^carphotos/', include('webui.photos.urls', app_name='car-photos') ),
(r'^userphotos/', include('webui.photos.urls',  app_name='profile-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 я хочу показать URL для создания нового альбома album_page.

Я обнаружил, что для получения правильного URL-адреса мне нужно использовать параметр current_app функции reverse.

Но как получить этот current_app? Я думал, что ответ прост. Но я не могу найти его в документации по Django.

Спасибо, Ник

Ответы [ 4 ]

11 голосов
/ 06 ноября 2012

Я знаю, что это довольно старый вопрос ... но я думаю, что нашел решение:

Как предположил Уилл Харди, вы должны будете оставить 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 %}

Чтобы отменить URL в представлениях, текущий экземпляр приложения должен быть передан вручную:

reverse('webui_photos:album-create', current_app=resolve(self.request.path).namespace))
1 голос
/ 09 января 2010

В ваших URL у вас есть другое 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') ),)

Затем укажите аргумент current_app при использовании reverse. См http://docs.djangoproject.com/en/dev/topics/http/urls/#reverse и http://docs.djangoproject.com/en/dev/topics/http/urls/#url-namespaces

[править] после перечитывания вашего вопроса:

вам не нужно указывать аргумент current_app, если вы используете тег {% url %}. Насколько я могу поверить, он автоматически получит доступ к переменной шаблона с именем current_app, которая автоматически устанавливается на основе соответствующего URL-адреса.

0 голосов
/ 11 января 2010

После изучения этой темы в течение нескольких дней я обнаружил, что монтировать приложение django несколько раз не естественно.

Существует реализация шаблона подключаемых приложений: http://github.com/nowells/django-pluggables. Это выглядит слишком сложно для меня.

Поэтому я решил перенести повторяющиеся функции в пользовательские теги и дубликаты шаблонов для каждого использования моего приложения. Я надеюсь, что использование пользовательских тегов и расширенных функций поможет мне следовать принципу СУХОЙ.

0 голосов
/ 08 января 2010

Полагаю, для этого и нужна sites платформа.

...