【问题标题】: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'

标签: python django django-urls urlconf


【解决方案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/' 时:

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

在视图中:

  1. 它通过查看与应用程序命名空间(真实名称)关联的 urls 文件来反转 URL,并将名称反转为:create/success
  2. 然后它返回到链上,现在使用实例命名空间(昵称)来添加 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 路径。

    我希望这对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-10
      • 2011-12-10
      • 2017-03-13
      • 2012-07-10
      • 1970-01-01
      • 2020-08-21
      • 1970-01-01
      • 2019-02-01
      相关资源
      最近更新 更多