我查阅了django文档,它提到当在django项目中使用同一应用程序的多个实例时,实例命名空间和应用程序命名空间就会出现。
但我仍然无法理解它。我已经在谷歌上搜过了,但没有找到任何帮助。
提前致谢。
将实例命名空间视为您的昵称,将应用程序命名空间视为您的真实姓名。
人们可以为您取很多昵称,但您的真实姓名不会改变。
Django使用应用程序命名空间(您的真实姓名)来反向生成URL,因为作为一个应用程序,您不需要关心有多少个实例命名空间(昵称)。
但为了区分一个实例和下一个实例,在urlconfs中将使用实例命名空间(昵称)。
假设您的应用程序涉及客户和商店员工。这两者都有物理地址,您可能希望使用一个只处理所有地址信息的应用程序:表单、验证、模型结构、地理位置等。我们虚构的应用程序是一个可重用的Django应用程序,名为 "django_super_address"。
您的根URL配置可能如下所示:
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'
)
...
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')),
]
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'),
...
]
app_name
属性定义namespace
参数定义author-polls
和publisher-polls
都使用相同的polls.urls
来解析它们的URL。如果没有实例命名空间,解析类似'polls:index'的URL可能会让人困惑,不知道它要获取哪个URL。这就是为什么Django有一组协议,用于解决所有类型的情况,当您尝试反转和解析命名空间的URL时。命名空间实例只能与include一起使用。当我们想要有多个具有不同URL的路径,但是我们想要包含相同的URLconf模块时,这非常有用。
假设我们有以下代码:
#my_site/urls.py
urlpatterns = [
path('url1/',include('english.urls')),
path('url2/',include('english.urls'))]
#english/urls.py
app_name='english'
urlpatterns = [
path('words/', views.index, name='words')]
#template.html
<a href="{% url 'english:words' %}">Something</a>
#my_site/urls.py
urlpatterns = [
path('url1/',include('english.urls', namespace='eng')),
path('url2/',include('english.urls', namespace='eng2'))]
#english/urls.py
app_name='english'
urlpatterns = [
path('words/', views.index, name='words')]
然后:
#template.html
<a href="{% url 'eng2:words' %}">Something</a>
我要补充一点,如果没有实例命名空间,Django 可能会发出警告:
警告:?(urls.W005) URL 命名空间 'english' 不是唯一的。您可能无法反向解析此命名空间中的所有 URL。
通常,在以下情况下实例命名空间很有用:
这不仅限于不同的 URL。即使我们使用相同的视图,我们也可以根据所在的 URL 稍微修改它们:
def index(request):
current_url = request.path
if current_url == '/url1/words/':
''' do something '''
elif current_url == '/url2/words/':
''' do something else '''
return render(request, 'template.html')
url2/words
。我是对的吗? - S.B基本上每个应用程序命名空间都可以有多个实例命名空间,例如:
这是项目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.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