Создание сайта на Python/Django: URLs и пространство имен
На текущий момент мы уже создали несколько полезных представлений (views) для нашего сайта на Django. Как мы уже знаем, представления созданы для того, чтобы получать данные модели, как-то их там обрабатывать и возвращать результат. Возврат результата происходит путем его передачи в систему шаблонов вывода. Давайте вернемся к шаблону detail.html и сделаем его немного лучше, добавив следующий код:
# polls/templates/polls/detail.html <h1>{{ question.question_text }}</h1> <ul> {% for choice in question.choice_set.all %} <li>{{ choice.choice_text }}</li> {% endfor %} </ul>
Давайте немного разберемся, что за синтаксис был использован в данном шаблоне. Из представления detail мы передали объект question. Создавая модель Question мы добавляли в нее несколько полей и чтобы получить к ним доступ используется точка “.”. В данном случае {{ question.question_text }} выводит ни что иное, как тест вопроса.
Далее в цикле {% for %} … {% endfor %} происходит вывод перечня связанных вариантов ответа question.choice_set.all с формированием списка. Более подробно с системой шаблонов Джанго можно ознакомиться в документации по шаблонам.
Избавляемся от “жестких” ссылок в шаблонах
Когда мы кодировали ссылку на вопрос в шаблоне polls/index.html, ссылка была частично жестко закодирована следующим образом:
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
Проблема “жестких” ссылок заключается в том, что при большом их количестве в проекте, становится сложно их поддерживать рабочими. Чтобы облегчить процесс, при задании path() в polls.urls мы указали аргумент name. Теперь, используя значение этого аргумента, мы может заменить строку кода с использованием тэга {% url %}следующим образом:
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
Функция url ищет соответствующее имя в urls.py приложения и генерирует соответствующий адрес. Теперь, если вы захотите внести коррективы в адрес представления, например, так:
# Сейчас path('<int:question_id>/', views.detail, name='detail'), # Вариант изменения path('specifics/<int:question_id>/', views.detail, name='detail'),
То, ссылки в шаблоне продолжат работать, т.к. будут автоматически изменены на новый формат везде, где ссылка была создана функцией url с указанием name=’detail’ .
Пространство имен URL
Наше приложение пока имеет в составе всего одно приложение. Реальные проекты на Джанго могут включать множество приложений, вплоть до нескольких десятков. Возникает вопрос, как сделать так, чтобы Джанго знал, к какому представлению необходимо обращаться при указании, например, detail в качестве параметра функции url, если представления с таким имененм могут быть в разных приложениях?
Для этого необходимо создать пространство имен в polls/urls.py, указав app_name, например, так:
# polls/urls.py from django.urls import path from . import views app_name = 'polls' urlpatterns = [ path('', views.index, name='index'), path('<int:question_id>/', views.detail, name='detail'), path('<int:question_id>/results/', views.results, name='results'), path('<int:question_id>/vote/', views.vote, name='vote'), ]
Далее, изменяем ссылку в polls/index.html:
# polls/templates/polls/index.html # Было до создания пространства имен <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
На следующий вариант с указанием пространства имен:
# polls/templates/polls/index.html # Стало с указанием пространства имен <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
На этом этапе мы разобрались, как создать простые представления в Джанго, как создать пространство имен для формирования ссылок на представления. Далее перейдем к рассмотрению вопросов по обработке пользовательских форм, общему улучшению кода, улучшению функциональности нашего приложения.