Django urls.py 中 app_name 的目的是什么?

What is the purpose of app_name in urls.py in Django?

当从 Django 应用程序 include()ing urlconf 到项目的 urls.py 时,某种应用程序的名称(或名称空间)应指定为:

因为我猜是 Django 2,所以第二种方法是首选方法,尽管我从 Django 3 文档中复制粘贴了第一个函数签名。但这不是重点。

我目前对include()namespace参数的理解是我在使用reverse()时使用的。

应用程序 urls.py 中的 app_name 或主 urls.py 中的 app_namespace 的目的是什么?
这些是完全一样的东西吗?
Django 是如何使用它的?

我在这里找到的现有问题(和答案)解释了我应该如何指定它而不是为什么。

来自 https://docs.djangoproject.com/en/3.0/topics/http/urls/#introduction :

URL namespaces allow you to uniquely reverse named URL patterns even if different applications use the same URL names. It’s a good practice for third-party apps to always use namespaced URLs (as we did in the tutorial). Similarly, it also allows you to reverse URLs if multiple instances of an application are deployed. In other words, since multiple instances of a single application will share named URLs, namespaces provide a way to tell these named URLs apart.

app_name in app/urls.py 和 app_namespace in include((pattern_list, app_namespace), namespace=None) in main urls.py 与 application namespace 的引用相同,它描述了正在部署的应用程序的名称。

可以将整个 app/urls.py 或带有 app_name 的 app/urls.py 的字符串引用传递给 include()

# blog.urls
from django.urls import path

from . import views

app_name = 'blog'
urlpatterns = [
    path('', views.index(), name='index'),
    path('<int:pk>/', views.post(), name='detail'),
]
# project urls
from django.urls import include, path

urlpatterns = [
    path('', include('blog.urls')),
]

url 模式和 app_namespace 到 include()

的元组
# project urls
from django.urls import include, path
from blog.urls import urlpatterns as blogpatterns

urlpatterns = [
    path('', include((blogpatterns, 'blog'))),
]

app_namespace 将是 include() 中提供的默认应用程序名称 space。如果未提供 app_namespace,则它将在 blog/urls.py 中查找 app_name,这将是默认名称 space.

如果没有应用程序名称space,url 将添加到全局名称space,这可能会导致 url 冲突。

URL namespaces and included URLconfs | Term application namespace | include()

在这个回答中,我选择 DRF package and its URL patterns。如果您想尝试此答案中提到的任何片段,您必须安装 (pip install djangorestframework) 并将 rest_framework 添加到 INSTALLED_APPS 列表。


应用程序命名空间可以通过两种方式设置,[参考:Django doc]

  1. urls.py 中使用 app_name 变量。

    可以看到DRF在urls.py中设置了app_name。 Django 将使用此 app_name 作为 应用程序命名空间 仅当我们包含 模块引用 [= 的模式时94=].

    include(module, namespace=None)

    示例:

    urlpatterns = [  
     path('drf-auth/bare/', <b>include('rest_framework.urls')</b>),  
    ]
    
  2. include((pattern_list, app_namespace), namespace=None) 函数中使用 app_namespace 参数。

    在此方法中,如果需要,您可以为应用程序设置一个 附加 app_namespace

    最重要的是,我们传递的是 pattern_list 而不是 模块

    示例:

    <b>from rest_framework.urls import urlpatterns as drf_urlpatterns</b>
    
    urlpatterns = [  
       path('drf-auth/foo/', include(<b>(drf_urlpatterns, 'foo-app-namespace')</b>)),  
    ]
    

完整示例

from django.urls import path, include, reverse  
from rest_framework.urls import urlpatterns as drf_urlpatterns  
  
urlpatterns = [  
  path('drf-auth/bare/', include('rest_framework.urls')),  
  path('drf-auth/foo/', include((drf_urlpatterns, 'foo-app-namespace'))),  
  path('drf-auth/bar/', include((drf_urlpatterns, 'bar-app-namespace'))),  
]  

print(reverse('rest_framework:login'))
print(reverse('foo-app-namespace:login'))
print(reverse('bar-app-namespace:login'))

#results
/drf-auth/bare/login/
/drf-auth/foo/login/
/drf-auth/bar/login/

  1. What is the purpose of app_name in app's urls.py or app_namespace in main urls.py?

两者都用于设置应用程序命名空间app_name 可以用作 默认应用程序命名空间 ,如果在 urls.py.

中定义
  1. Are these exactly the same thing?

没有

  1. How is it used by Django?

应用程序命名空间实例命名空间 用于检索 URL 路径。在 Django 中,每当 reverse(...) function get executed, Django looking for an application namespace first, than any other. You can read more about how Django resolve the URL here, Reversing namespaced URLs

多年来,我们(在 Django)一直在回避应用程序名称(space)和实例名称space 之间的(令人困惑的)区别。根据文档中的示例,我们一直只建议使用实例名称space。

Django 2.0(及更高版本)发生的事情是他们已经做到了,因此您不能在不(首先)使用应用程序名称的情况下使用实例名称space。我们应该将示例更新为正确的用法,而不是修复代码。

包含需要像这样:

urlpatterns += [ url('API/', include((router.urls, 'pikachu')) ]

趋势是也包括第二个 namespace='pikachu' 实例名称space 参数,但这不是必需的 — 它默认为 None 并设置为 'pikachu'在这种情况下自动。

通常,用户希望包含一个 app-level URL 模块,在那里明确设置 app_name 属性,而不是手动包含路由器。