В чем разница между пространством имен экземпляра и пространством имен приложения в URL-адресах django?
Я имею в виду https://www.webforefront.com/django/namedjangourls.html чтобы понять django urlconfs. Я столкнулся с терминами пространства имен экземпляра и пространства имен приложения. Я знаю о пространствах имен в urlsconfs. Но я не знаю разницу между ними.
Я отослал документы Django для этого. В нем упоминается, что пространства имен экземпляра и приложения появляются, когда в проекте django используется несколько экземпляров одного и того же приложения.
Но все же я не могу этого понять. Я погуглил, но не смог найти никакой помощи по этому вопросу.
Заранее спасибо.
5 ответов
Думайте о пространстве имен экземпляра как о вашем псевдониме, а пространство имен приложения - как о вашем реальном имени.
Люди могут иметь много прозвищ для вас, но ваше настоящее имя не меняется.
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'
)
...
Когда Django получает URL `/employee/address/create/':
- Он устанавливает пространство имен экземпляра в
customer_address
- Это читает URL от
django_super_address
- Он устанавливает пространство имен приложения в
django_super_address
и связывает urls.py с этим пространством имен приложения.
По мнению:
- Он переворачивает URL, просматривая файл URL, связанный с пространством имен приложения (реальное имя), и переворачивает имя в:
create/success
- Затем он возвращается по цепочке, используя пространство имен экземпляра (псевдоним) для добавления остальной части URL:
root
+employee/address/
+create/success/
знак равно/employee/address/create/success/
И вот, у вас есть: псевдонимы для urlconfs и пространства имен приложений для reverse!
Насколько я понимаю, это выглядит так:
- Для двух разных приложений, использующих один и тот же шаблон URL, используйте пространство имен Application.
- Для двух разных экземпляров одного и того же приложения, использующего одну и ту же конфигурацию URL и представления, используйте пространство имен Instance.
Применение пространства имен 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'),
...
]
Пространства имен определены следующим образом:
- Пространство имен приложения определяется
app_name
атрибут в опросах / urls.py - Пространство имен Instance определяется
namespace
аргумент в urls.py
Здесь оба author-polls
а также publisher-polls
используют то же самое polls.urls
разрешить их URL. Без пространства имен экземпляра разрешение URL-адреса, такого как "polls:index", может создать путаницу по тому, какой 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>
Щелчок по ссылке перенаправит нас на url1/words, потому что Django выберет первый элемент из urlpatterns. Если мы хотим, чтобы нас перенаправили на url2/words, мы должны использовать пространство имен (instance namespace), то есть:
#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-адреса в зависимости от родного языка пользователя, например: 'django/documentation/', 'django/dokumentacja/' или 'django/en', 'django/pl'
- мы хотим разделить URL-адреса для определенных групп людей: «amazon/clients/», «amazon/employees».
- мы изменили 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')
Мы можем, например, изменить контекст или выбрать другой шаблон.
Вы можете использовать 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/
в основном каждое пространство имен приложения может иметь несколько пространств имен экземпляров, например:
это файл 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>
в конце:
пространство имен приложения и пространство имен экземпляра помогут вам определить / выбрать правильный путь URL из нескольких путей URL, которые используют один и тот же включаемый файл .urls.
Надеюсь, это поможет вам.