django url中的实例命名空间和应用程序命名空间有啥区别?

Posted

技术标签:

【中文标题】django url中的实例命名空间和应用程序命名空间有啥区别?【英文标题】:What is difference between instance namespace and application namespace in django urls?django url中的实例命名空间和应用程序命名空间有什么区别? 【发布时间】:2018-08-20 14:41:11 【问题描述】:

我指的是https://www.webforefront.com/django/namedjangourls.html 来了解django urlconfs。我遇到过术语实例命名空间和应用程序命名空间。我知道 urlsconfs 中的命名空间。但我不知道它们之间的区别。

我为此参考了 django 文档。它提到当在 django 项目中使用同一应用程序的多个实例时,实例和应用程序命名空间就会出现。

但是,我仍然无法理解它。我已经用谷歌搜索了,但找不到任何帮助。

提前致谢。

【问题讨论】:

不确定问题是什么,但 Django 使用 url conf 中的 namespace 参数来确定查找应与视图函数名称匹配的位置,即 'admin:index' admin 是应用程序命名空间,因为 admin 是django项目中的应用。并在 views.py 模块中索引视图函数。默认情况下可以更改命名空间,它使用带有app_name 的应用程序模块,或者可以在Django2.0 的情况下将其添加到url.py app_name = 'your_app_name' 【参考方案1】:

将实例名称空间视为您的昵称,将应用程序名称空间视为您的真实姓名。

人们可以给你很多昵称,但你的真名不会改变。

Django 使用应用程序命名空间(你的真实姓名)来反转 url,因为作为一个应用程序你不应该关心有多少实例命名空间(昵称)。

但是为了区分一个实例和下一个实例,您将在 urlconfs 中使用实例命名空间(昵称)。

假设您的应用与客户和商店员工打交道。这两个都有物理地址,您可能希望使用只处理所有地址信息的应用程序:表单、验证、模型结构、地理位置等。我们虚构的应用程序是一个名为“django_super_address”的可重复使用的 django 应用程序。

您的根 url conf 可能如下所示:

urlpatterns = [
    path('customer/address/',
         include('django_super_address.urls',
         namespace='customer_address')
    ),
    path('employee/address/',
         include('django_super_address.urls',
         namespace='employee_address')
    ),
]

这包括不同 URL 路径下的相同 url,指向同一个应用,使用不同的命名空间(昵称)。

django_super_address 中,它定义了它的应用程序命名空间:

# File: django_super_address/urls.py
from . import views
app_name = 'django_super_address'

urlpatterns = [
    path('create/', views.SomeAddressCreateView.as_view(),
         name='address_create'),
    path('create/success/', views.SuccessView(),
         name='address_create_success'),
    ...
]

在它使用的视图中:

# File django_super_address/views.py
class SomeAddressCreateView(generic.CreateView):
    def success_url(self):
        return reverse(
           'django_super_address:address_create_success'
        )
    ...

当 Django 获取 URL `/employee/address/create/' 时:

    它将实例命名空间设置为employee_address 它从django_super_address读取url 它将应用程序命名空间设置为django_super_address 和 将 urls.py 与该应用程序命名空间相关联。

在视图中:

    它通过查看与应用程序命名空间(真实名称)关联的 urls 文件来反转 URL,并将名称反转为:create/success 然后它返回到链上,现在使用实例命名空间(昵称)来添加 URL 的其余部分:root + employee/address/ + create/success/ = /employee/address/create/success/

你有它:urlconfs的昵称和reverse的应用程序命名空间!

【讨论】:

我感到困惑的部分是为什么我会有两个指向同一个应用程序的 url 结构?这似乎是一个小众用例。 如果我可能会问,为什么admin:index 是在互联网上其他地方用来回答这个问题的例子? index 不是视图名不是实例命名空间吗? 我正在尝试进行 drf 命名空间版本控制。我在 /urls.py 文件中缺少 app_name。有了这个解释,我就能理解并使用它。【参考方案2】:

据我了解,是这样的:

对于使用相同 URL 模式的两个不同应用程序,请使用 应用程序命名空间。 对于使用相同 URL 配置和视图的同一应用程序的两个不同实例,请使用 实例命名空间

Instance 命名空间的应用可能听起来有点混乱。让我试着澄清一下是否是这样。考虑Django docs 中给出的示例。

urls.py:

from django.urls import include, path

urlpatterns = [
path('author-polls/', include('polls.urls', namespace='author-polls')),
path('publisher-polls/', include('polls.urls', namespace='publisher-polls')),
]

投票/urls.py:

from django.urls import path

from . import views

app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
...
]

命名空间的定义如下:

应用程序命名空间polls/urls.py 中的app_name 属性定义 Instance namespaceurls.py 中的 namespace 参数定义

在这里,author-pollspublisher-polls 都使用相同的 polls.urls 来解析它们的 URL。如果没有 Instance 命名空间,解析像 'polls:index' 这样的 URL 可能会混淆它打算获取的 URL。这就是为什么 Django 定义了一组 protocol 来在您尝试反转和解析命名空间 URL 时针对各种情况解决此问题。

【讨论】:

这是不正确的。特别是“对于使用相同 URL 模式的两个不同应用程序,请使用应用程序命名空间。”。【参考方案3】:

您可以通过将 urls.py 包含在不同的 url 路径中来将其用于应用程序,例如我们可以:

urlpatterns = [
    path('author-polls/', include('polls.urls')),
    path('publisher-polls/', include('polls.urls')), 
]

如您所见,两者都包含 polls.urls,即:

app_name = 'polls' urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
    ... 
]

到目前为止一切顺利!

但是有一个问题。在模板中,'polls:index' 指向哪里?! 现在实例命名空间出现了。

urlpatterns = [
    path('author-polls/', include('polls.urls', namespace='author-polls')),
    path('publisher-polls/', include('polls.urls', namespace='publisher-polls')), 
]

Django 有一些规则来反转命名空间 url >> https://docs.djangoproject.com/en/3.0/topics/http/urls/#reversing-namespaced-urls

【讨论】:

【参考方案4】:

基本上每个应用命名空间可以有多个实例命名空间, 例如:

这是项目 URL 文件(主 url):

path('', include("movie_app.urls")),
path('my_namespace1/', include("movie_app.urls", namespace='my_namespace1')),
path('my_namespace2/', include("movie_app.urls", namespace='my_namespace2')),

你可以看到,他们都提到了同一个app.urls文件(movie_app.urls),但是路径链接不同。

第一个是:"",

第二个是:“my_namespace1/”,

第三个是:“my_namespace2/”,

这是 movie_app.urls 文件(子文件):

app_name = 'movie_app'

urlpatterns = [
    path('appmovie1/', myview1 , name="myname"),   

]

现在当您使用 html 模板中的所有路径时:

    <h1><a href="% url 'movie_app:myname' %"> application namespace : url name</a></h1>
    <h1><a href="% url 'my_namespace1:myname' %">instance namespace1 : url name</a></h1>
    <h1><a href="% url 'my_namespace2:myname' %">instance namespace2 : url name </a></h1>
  

您会注意到 href 链接中的不同:

    <h1><a href="/appmovie1/"> application namespace : url name</a></h1>
    <h1><a href="/my_namespace1/appmovie1/">instance namespace1 : url name</a></h1>
    <h1><a href="/my_namespace2/appmovie1/">instance namespace2 : url name </a></h1>
  

最后:

应用名称空间和实例名称空间将帮助您从使用相同包含 .urls 文件的多个 URL 路径中确定/选择正确的 URL 路径。

我希望这对你有帮助。

【讨论】:

以上是关于django url中的实例命名空间和应用程序命名空间有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Django命名空间app_name和namespace

django-URL实例命名空间

django2中带有router.urls的命名空间

017:应用命名空间和实例命名空间

基于请求命名空间解析 URL

Django(命名空间)