Как работать с URL-адресами пространств имен в многоразовом приложении Django

Я боролся с изменением URL-адресов с помощью многоразового приложения Django. Вот основная схема моей проблемы.

Многоразовое приложение:

В файле urls.py он имеет следующий шаблон:

url(r'^object-list/$', ObjectListView.as_view(), name='object-list')

Где-то в views.py многоразового приложения есть следующий обратный вызов:

reverse('object-list')

Мой проект:

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

url(r'^app-stuff/', include('app.urls', namespace='app'))

Проблема:

Это приводит к тому, что все обратные вызовы в приложении выдают NoReverseMatch исключение при попытке поиска object-detail, потому что URL-адрес теперь имеет имя app:object-detail.

У меня есть доступ к рассматриваемому приложению, поэтому я могу изменить вызываемые им вызовы на reverse, но я хотел бы сделать это таким образом, чтобы не было жесткого кодирования пространства имен. Я прочитал документацию по аргументам current_app и namespace функции include, но не совсем понимаю, помогут ли они решить возникшую у меня проблему.

Мы очень ценим любые ваши предложения.


person Chathan Driehuys    schedule 27.06.2016    source источник


Ответы (1)


Я решил это, прочитав документы Django по Разрешение URL более внимательно.

Если у вас есть многоразовое приложение с именем myapp, вы можете добавить свойство app_name в его конфигурацию URL-адреса, чтобы дать ему пространство имен приложения. Пример:

# myapp/urls.py

app_name = 'myapp'

urlpatterns = [
    url(r'^index/$', IndexView.as_view(), name='index')
]

Теперь, даже если URL-адреса приложения включены так:

# project/urls.py

urlpatterns = [
    url(r'^myapp/', include('myapp.urls', namespace='random-namespace')),
]

... URL-адреса по-прежнему доступны с использованием reverse('myapp:index').

Если вы хотите увидеть это более подробно, я создал небольшой репозиторий GitHub с примером.

Изменить:

Указание свойства app_name в urls.py работает только в Django 1.9 и новее. Для Django 1.8 вы должны использовать параметр app_name в функции include().

person Chathan Driehuys    schedule 30.06.2016
comment
Спасибо. Однако это решение, похоже, не работает для вложенных приложений. - person pymarco; 21.11.2016
comment
@pymarco Можете ли вы предоставить дополнительную информацию по этому поводу? Если возможно, не могли бы вы сделать запрос на перенос в репозиторий, который показывает проблему? - person Chathan Driehuys; 21.11.2016
comment
Спасибо за ответ. Я только что разместил отдельный вопрос SO. stackoverflow.com/questions/40709613/ - person pymarco; 21.11.2016