В чем разница между пространством имен экземпляра и пространством имен приложения в 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/':

  1. Он устанавливает пространство имен экземпляра в customer_address
  2. Это читает URL от django_super_address
  3. Он устанавливает пространство имен приложения в django_super_address и связывает urls.py с этим пространством имен приложения.

По мнению:

  1. Он переворачивает URL, просматривая файл URL, связанный с пространством имен приложения (реальное имя), и переворачивает имя в: create/success
  2. Затем он возвращается по цепочке, используя пространство имен экземпляра (псевдоним) для добавления остальной части 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.

Надеюсь, это поможет вам.

Другие вопросы по тегам