URL-адреса Django и include() — как вы различаете 2 URL-адреса с одинаковым «именем» в 2 отдельных приложениях?

#django #django-urls

#django #django-urls

Вопрос:

В моем проекте есть 2 приложения: «посадка» и «новости». Прямо сейчас у меня настроены URL-адреса следующим образом:

project/urls.py:

 urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('landing.urls')),
    path('news/', include('news.urls')),
]
 

project/landing/urls.py:

 urlpatterns = [
    path('', landing_view, name='landing'),
]
 

project/news/urls.py:

 urlpatterns = [
    path('', news_view, name='news'),
]
 

ссылки на hrefs навигационной панели:

 href="{% url 'landing' %}"
href="{% url 'news' %}"
 

Я считаю, что эта настройка довольно стандартная, и пока все работает нормально. Что мне не нравится, так это то, что эта настройка зависит от того, что каждое приложение имеет уникальные имена для каждого пути url. Я хотел бы иметь возможность указывать приложение при ссылке на имя URL. Таким образом, мне не пришлось бы беспокоиться о случайном повторном использовании одного и того же имени для URL-адреса в разных приложениях.

В документации упоминается использование параметров app_name / namespace, но они не дают никаких примеров того, как ссылаться на URL-адрес в теге url.

Я пробовал что-то вроде этого:

project/urls.py:

 urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('landing.urls', namespace='landing', app_name='landing')),
    path('news/', include('news.urls', namespace='news', app_name='news')),
]
 

project/landing/urls.py:

 urlpatterns = [
    path('', landing_view, name='index'),
]
 

project/news/urls.py:

 urlpatterns = [
    path('', news_view, name='index'),
]
 

ссылки на hrefs навигационной панели:

 href="{% url 'landing:index' %}"
href="{% url 'news:index' %}"
 

Но я получаю эту ошибку:

     path('', include('landing.urls', namespace='landing', app_name='landing')),
TypeError: include() got an unexpected keyword argument 'app_name'
 

Удалите параметр app_name, и я получаю конфликтующую ошибку:

 path('', include('landing.urls', namespace='landing')),
  File "D:Devmy_sitevenvlibsite-packagesdjangourlsconf.py", line 38, in include
    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.
 

Я неправильно использую функциональность namespace / app_name или есть что-то еще, чего мне не хватает?

Ответ №1:

Вы должны указать разные пространства имен, и app_name=… это недопустимый параметр для include(…) . На самом деле вам вообще не нужно пространство имен, вы можете в обоих urls.py указать app_name :

 # landing/urls.py

app_name = 'landing'

urlpatterns = [
    path('', landing_view, name='index'),
] 

и:

 # news/urls.py

app_name = 'news'

urlpatterns = [
    path('', news_view, name='index'),
] 

затем вы можете импортировать их с помощью:

 urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('landing.urls')),
    path('news/', include('news.urls')),
] 

затем вы можете обратиться к app_name :

 href="{% url 'landing:index' %}"
href="{% url 'news:index' %}" 

Если вы хотите переопределить пространство имен include, вы можете указать это с namespace=… помощью параметра, поэтому:

 urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('landing.urls', namespace='otherlanding')),
    path('news/', include('news.urls')),
] 

затем вы, таким образом, переписываете это в:

 href="{% url 'otherlanding:index' %}"
href="{% url 'news:index' %}" 

Комментарии:

1. Это # landing/urls.py опечатка? вместо # news/urls.py

2. @ArakkalAbu: нет, это ошибка копирования-вставки 🙂