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 namespace 由 urls.py 中的 namespace
参数定义
在这里,author-polls
和 publisher-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中的实例命名空间和应用程序命名空间有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章