Django URL 和 include() - 你如何区分 2 个独立应用程序中具有相同 "name" 的 2 个 url?

Django URLs and include() - how do you differentiate between 2 urls with the same "name" in 2 separate apps?

我的项目中有两个应用程序,“着陆”和“新闻”。现在,我的 URLs 配置如下:

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'),
]

导航栏link 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'),
]

导航栏link 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:\Dev\my_site\venv\lib\site-packages\django\urls\conf.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 功能还是缺少其他东西?

您应该指定 不同的 名称空间,并且 app_name=… 不是 include(…) 的有效参数。实际上,您首先不需要命名空间,您可以在 urls.py 中指定一个 app_name:

# landing/urls.py

<b>app_name = 'landing'</b>

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

和:

# news/urls.py

<b>app_name = 'news'</b>

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 '<b>landing:</b>index' %}"
href="{% url '<b>news:</b>index' %}"

如果你想覆盖包含的命名空间,你可以用namespace=…参数指定,所以:

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

然后你将其重写为:

href="{% url '<b>otherlanding:</b>index' %}"
href="{% url '<b>news:</b>index' %}"