在Django中的urls.py文件中,app_name的作用是什么?

22
当从Django应用程序的urlconf包含到项目的urls.py时,需要指定某种应用程序名称(或命名空间),如下所示:
  • 主urls.py中使用include((pattern_list,app_namespace),namespace = None)的app_namespace
或者
  • 应用程序的urls.py中的app_name变量。
自Django 2以来,第二种方法是首选,尽管我从Django 3文档中复制了第一个函数签名。 但这不是重点。
我对include()的命名空间参数的理解是在使用reverse()时使用它。
应用程序的urls.py中的app_name或主urls.py中的app_namespace的目的是什么?它们完全相同吗?Django如何使用它?
我找到的现有问题(和答案)解释了我应该如何指定它而不是为什么。

3
文档中有一个示例,解释得非常清楚。 - Kevin Christopher Henry
6个回答

16

在这个答案中,我将使用DRF包及其URL模式。如果您想尝试本答案提到的任何代码片段,则必须安装(pip install djangorestframework)并将rest_framework添加到INSTALLED_APPS 列表中。


应用程序命名空间有两种设置方式,[参考:Django文档]

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

    您可以看到DRF在urls.py中设置了app_name。仅当我们使用模块引用包含模式时,Django才会将此app_name用作应用程序命名空间

    也就是说,include(module, namespace=None)

    示例:

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

    通过这种方法,您可以为应用程序设置一个额外的app_namespace(如果需要)。

    最重要的是,我们传递了一个模式列表而不是模块

    示例:

    <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. urls.py文件中的app_name或主urls.py中的app_namespace有什么作用?

    这两个都用于设置应用程序命名空间。如果在urls.py中定义了app_name,则可以将其用作默认应用程序命名空间

    1. 它们完全相同吗?

    不是完全相同的。

    1. Django如何使用它?

    应用程序命名空间实例命名空间用于检索URL路径。在Django中,每当执行reverse(...)函数时,Django首先查找应用程序命名空间,然后才查找其他命名空间。您可以在此处阅读有关Django如何解析URL的更多信息:反向命名空间URL


    4
    在app/urls.py文件中,app_name和主urls.py中的include((pattern_list, app_namespace), namespace=None)中的app_namespace被称为应用程序命名空间,它描述了正在部署的应用程序的名称。
    您可以通过传递整个app/urls.py文件或带有app_name的字符串引用来使用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模式和应用程序命名空间的元组,可以使用 include() 函数进行包含。

    # project urls
    from django.urls import include, path
    from blog.urls import urlpatterns as blogpatterns
    
    urlpatterns = [
        path('', include((blogpatterns, 'blog'))),
    ]
    

    app_namespace是在include()提供时的默认应用程序命名空间。如果没有提供app_namespace,则会在blog/urls.py中查找app_name,并将其作为默认命名空间。

    没有应用程序命名空间,URL将被添加到全局命名空间中,这可能会导致URL冲突。

    URL命名空间和包含的URLconfs | 术语应用程序命名空间 | include()


    2
    多年来,在 Django 中,我们一直绕过应用程序名称(空间)和实例命名空间之间(容易混淆的)区别。我们一直推荐使用实例命名空间,正如文档中的示例一样。
    但是,从 Django 2.0 开始,他们使得在不首先使用应用程序名称的情况下无法使用实例命名空间。因此,我们需要更新示例以使用正确的方式,而不是修复代码。
    包含内容应该像这样:
    urlpatterns += [ url('API/', include((router.urls, 'pikachu')) ]
    

    倾向于包含第二个namespace='pikachu'实例的命名空间参数,但这不是必需的 - 它默认为None,并在这种情况下自动设置为'pikachu'

    通常,用户希望显式地包含一个应用级别的URL模块,在那里设置app_name属性,而不是手动包含路由器。


    -1

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

    URL 命名空间允许您唯一地反转命名的 URL 模式,即使不同的应用程序使用相同的 URL 名称。对于第三方应用程序来说,始终使用命名空间 URL(就像我们在教程中所做的那样)是一个好习惯。同样,它还允许您反转 URL,如果部署了多个应用程序实例。换句话说,由于单个应用程序的多个实例将共享命名的 URL,因此命名空间提供了一种区分这些命名 URL 的方法。


    1
    如果我理解正确,这段文字解释的是实例命名空间的目的,而不是 APP 命名空间。问题是关于后者的。 - Den Kasyanov

    -1

    app_name 在项目中帮助纠正不同应用程序之间具有相同名称(用于URL)的歧义。


    这并没有回答问题。一旦你拥有足够的声望,你就可以评论任何帖子;相反,提供不需要提问者澄清的答案。- 来自审查 - Ram Chander
    根据目前的写法,你的回答不够清晰。请编辑以添加更多细节,帮助其他人理解这如何回答所提出的问题。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - Community

    -1
    TLDR;
    app_name设置了当前应用程序的URL命名空间。当您想要使用reverse函数反转URL(即生成URL)时,命名空间非常有用。它确保该应用程序的URL不会与其他应用程序的URL冲突。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接