Как справиться с 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
функционировать, но я не совсем понимаю, помогут ли они решить проблему, с которой я столкнулся.
Будем очень благодарны за любые ваши предложения.
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()
функция.