【问题标题】:What is the purpose of app_name in urls.py in Django?Django 中 urls.py 中 app_name 的用途是什么?
【发布时间】:2020-07-29 23:06:09
【问题描述】:

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

  • app_namespaceinclude((pattern_list, app_namespace), namespace=None) 在主要 urls.py

  • 应用程序的urls.py 中的app_name 变量。

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

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

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

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

【问题讨论】:

标签: django django-urls


【解决方案1】:

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


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

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

    可以看到 DRF 在urls.py 中设置了app_name。只有当我们将模式包含在 module reference 中时,Django 才会使用这个 app_name 作为 应用程序命名空间

    include(module, namespace=None)

    示例:

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

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

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

    示例:

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

完整示例

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 或主urls.py 中的app_nameapp_namespace 的用途是什么?

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

  1. 这些完全一样吗?

没有。

  1. Django 是如何使用它的?

应用程序命名空间实例命名空间用于检索 URL 路径。在 Django 中,每当reverse(...) 函数被执行时,Django 首先寻找应用程序命名空间,而不是其他任何方法。您可以在此处阅读有关 Django 如何解析 URL 的更多信息,Reversing namespaced URLs

【讨论】:

    【解决方案2】:

    app/urls.py 中的app_name 和主urls.py 中include((pattern_list, app_namespace), namespace=None) 中的app_namespaceapplication namespace 的引用相同,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() 中提供的默认应用程序命名空间。如果未提供app_namespace,则它将在blog/urls.py 中查找app_name,这将是默认命名空间。

    如果没有应用命名空间,则将 url 添加到全局命名空间中,这可能会导致 url 冲突。

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

    【讨论】:

      【解决方案3】:

      多年来,我们(在 Django)一直在绕开应用程序名称(空间)和实例命名空间之间(令人困惑的)区别。根据文档中的示例,我们一直只推荐使用实例命名空间。

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

      包含需要像这样:

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

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

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 如果我理解正确,这一段解释了(实例)命名空间的目的,而不是 APP 命名空间。问题是关于后者。
        猜你喜欢
        • 2015-04-16
        • 2015-12-24
        • 2015-10-10
        • 2014-08-07
        • 2022-11-13
        • 2019-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多