Задание
Создание проекта
Создание проекта
Создание проекта
Создание приложения
Создание приложения
Создание представления
URL
URL
path()
path()
Настройка базы данных
Настройка базы данных
Настройка базы данных
Настройка базы данных
Часовой пояс
Параметр INSTALLED_APPS
Параметр INSTALLED_APPS
Модели
Создание моделей
Создание моделей
Создание моделей
Создание моделей
Активация моделей
Активация моделей
Создание SQL
Создание SQL
Создание SQL
Создание таблиц в БД
Команда migrate
API
API
API
API
API
API
Административная часть Django
Административная часть Django
Вход в админку
Вход в админку
Добавление своего приложения в админку
Добавление своего приложения в админку
Представление
Представление
Представление
Представление
Представление
Представления
Представления
Шаблоны
Шаблоны
Шаблоны
Шаблоны
render()
Ошибка 404
Ошибка 404
get_object_or_404()
get_object_or_404()
get_object_or_404()
Система шаблонов
Система шаблонов
URL-адреса в шаблонах
URL-адреса в шаблонах
Пространство имен URL
Пространство имен URL
Минимальная форма
Минимальная форма
Минимальная форма
Минимальная форма
Минимальная форма
Минимальная форма
1.19M
Категория: ПрограммированиеПрограммирование

Лекция07 (django первый сайт)

1. Задание

*
* Создать базовое приложение для голосования
Он будет состоять из двух частей:
* Публичный сайт, который позволяет людям просматривать
опросы и голосовать в них.
* Сайт администратора, который позволяет добавлять,
изменять и удалять опросы.

2. Создание проекта

*
* В виртуальной среде, в каталоге в котором хотим сохранить
свой проект выполняем
* django-admin startproject mysite – это создаст
каталог mysite в текущем каталоге.
* Не рекомендуется в качестве названия проекта названия
встроенных компонентов Python или Django. Это значит, что
следует избегать использования таких имен,
как django (будет конфликт с самим фреймворком)
или test (будет конфликтовать со стандартным пакетом
Python).
*

3. Создание проекта

*
* Результат выполнения команды startproject:

4. Создание проекта

*
* Внешний корневой каталог mysite/ — это контейнер для вашего
проекта. Его имя не имеет значения для Django. Его можно
переименовать на что угодно.
* manage.py: утилита, позволяющая взаимодействовать с проектом
различными способами.
* Внутренний каталог mysite/ это Python модуль проекта. Его
название вы будете использовать для импорта чего-либо из этого
модуля (например, mysite.urls).
* mysite/__init__.py: пустой файл, который сообщает Python, что этот
каталог должен рассматриваться как пакет Python’а.
* mysite/settings.py: конфигурация и настройки проекта Django.
* mysite/urls.py: указание URL проекта на Django, можно сказать, что
это «оглавление» проекта.
* mysite/wsgi.py: точка входа для WSGI совместимых веб-серверов
для работы с проектом.
*

5. Создание приложения

*
* Приложение - это веб-приложение, которое что-то делает,
например, система Weblog, база данных публичных записей
или небольшое приложение для опроса. Проект - это набор
настроек и приложений для определенного сайта. Проект
может содержать несколько приложений. Приложение может
быть в нескольких проектах. manage.py: утилита,
позволяющая взаимодействовать с проектом различными
способами.
* Приложения могут находится где угодно в Python path
* Мы создадим приложение для опроса прямо рядом с
файлом manage.py, чтобы его можно было импортировать как
собственный модуль верхнего уровня, а не как
подмодуль` mysite`.

6. Создание приложения

*
* Создаем приложение

7. Создание представления

*
* В polls/views.py вставим следующий код
* Чтобы вызвать представление, нам нужно сопоставить его с URL - и
для этого нам нужен URLconf. Создадим его и добавим следующий код
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]

8. URL

*
* Следующим шагом является указание корневого URLconf на
модуль polls.urls. В mysite/urls.py добавьте импорт
django.urls.include и вставьте include() в список` urlpatterns`:
* Функция include() позволяет ссылаться на другие URLconfs.
Всякий раз, когда Django встречает include(), он отсекает
любую часть URL-адреса, совпадающую с этой точкой, и
отправляет оставшуюся строку во включенный URLconf для
дальнейшей обработки.

9. URL

*
* Идея, стоящая за include(), состоит в том, чтобы упростить
добавление и воспроизведение URL-адресов. Так как опросы
находятся в их собственном URLconf(polls/urls.py), их можно
поместить в «/polls/», или в «/fun_polls/», или в
«/content/polls/», или по любому другому корневому пути, и
приложение все равно будет работать.
* Вы всегда должны использовать include() при включении других
шаблонов URL. admin.site.urls - единственное исключение из
этого.
* Проверка. Запускаем сервер python manage.py runserver

10. path()

*
* Функция path() передает четыре аргумента, два обязательных:
route и view, и два необязательных: kwargs и name.
* Аргумент route
route - строка, содержащая шаблон URL. При обработке запроса
Django начинается с первого шаблона в urlpatterns и пробирается
вниз по списку, сравнивая запрошенный URL с каждым
шаблоном, пока не найдет тот, который соответствует.
Шаблоны не выполняют поиск параметров GET и POST или имени
домена. Например, в запросе к
https://www.example.com/myapp/
URLconf будет искать myapp/.
В запросе к
https://www.example.com/myapp/?Page=3
URLconf также будет искать только myapp/.

11. path()

*
* Аргумент view
Когда Django находит соответствующий шаблон, он вызывает
указанную функцию представления с объектом HttpRequest в
качестве первого аргумента и любые «захваченные» значения из
маршрута в качестве аргументов ключевого слова.
* Аргумент kwargs
Произвольные ключевые аргументы могут быть переданы в
словаре в целевое представление.
* Аргумент name
Присвоение имени URL-адресу позволяет вам однозначно
ссылаться на него из других мест Django, особенно из шаблонов.
Эта мощная функция позволяет вам вносить глобальные
изменения в шаблоны URL вашего проекта, касаясь только
одного файла.

12. Настройка базы данных

*
* mysite/settings.py. - это обычный модуль Python с переменными
уровня модуля, представляющими настройки Django.
* По умолчанию в конфигурации используется SQLite.
* Если использовать другую базу данных, необходимо установить
соответствующую bindings и изменить следующие ключи в параметре
DATABASES 'default', чтобы он соответствовал настройкам соединения с
вашей базой данных:
* ENGINE - 'django.db.backends.sqlite3', 'django.db.backends.postgresql',
'django.db.backends.mysql', или 'django.db.backends.oracle'.
* NAME - Название базы данных. Если вы используете SQLite, то БД
будет просто файлом на компьютере. В этом случае NAME должна
содержать полный абсолютный путь, включая имя файла. По
умолчанию используется os.path.join(BASE_DIR, 'db.sqlite3'), и
сохраняет файл в каталоге проекта.
* Если вы не используете SQLite в качестве базы данных, необходимо
добавить дополнительные настройки, такие как USER, PASSWORD и
HOST. Для получения дополнительной информации смотрите
справочную документацию для DATABASES.

13. Настройка базы данных

*
*

14. Настройка базы данных

*
*

15. Настройка базы данных

*
* Если вы используете базу данных отличную от SQLite,
убедитесь, что создали базу данных к этому моменту. Это
делается с помощью команды «CREATE DATABASE
database_name;» в интерактивной консоли базы данных.
* Также убедитесь, что пользователь базы данных, указанный в
mysite/settings.py, имеет права на создание базы данных.
* Если вы используете SQLite, вам не нужно ничего создавать
заранее - файл базы данных будет создан автоматически, когда
в этом возникнет необходимость.

16. Часовой пояс

*
* Во время редактирования mysite/settings.py, установите
TIME_ZONE в свой часовой пояс.
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

17. Параметр INSTALLED_APPS

*
* Он содержит имена всех приложений Django, которые активированы в
этом экземпляре проекта Django. Приложения могут использоваться в
нескольких проектах, и вы можете упаковывать и распространять их для
использования другими разработчиками в своих проектах.
* По умолчанию INSTALLED_APPS содержит следующие приложения, все из
которых поставляются с Django:
* django.contrib.admin - администраторская часть сайта.
* django.contrib.auth - система аутентификации.
* django.contrib.contenttypes - фреймворк типов данных.
* django.contrib.sessions – фреймвор сессий.
* django.contrib.messages – фреймворк сообщений.
* django.contrib.staticfiles – фреймворк для работы со статическими
файлами.
* Эти приложения включены по умолчанию для удобства для большинства
базовых задач.

18. Параметр INSTALLED_APPS

*
* Команда migrate просматривает настройку INSTALLED_APPS и
создает все необходимые таблицы базы данных в соответствии
с настройками базы данных в файле mysite/settings.py и
миграциями базы данных, поставляемыми с приложением
(рассмотрим их позже).

19. Модели

*
* Модели отображают информацию о данных, с которыми вы
работаете. Они содержат поля и поведение ваших данных.
Обычно одна модель представляет одну таблицу в базе данных.
Основы:
* Каждая модель это класс унаследованный от
django.db.models.Model.
* Атрибут модели представляет поле в базе данных.
* Django предоставляет автоматически созданное API для доступа
к данным.

20. Создание моделей

*
* В нашем приложении для опроса мы создадим две модели:
Question и Choice. Question содержит вопрос и дату публикации.
Choice содержит два поля: текст выбора и подсчет голосов.
Каждый Choice связан с Question.
* Эти понятия представлены классами Python. Отредактируйте
файл polls/models.py так, чтобы он выглядел следующим
образом:

21. Создание моделей

*

22. Создание моделей

*
* Здесь каждая модель представлена классом, который подкласс
django.db.models.Model. Каждая модель имеет несколько
переменных класса, каждая из которых представляет поле базы
данных в модели.
* Каждое поле представлено экземпляром класса Field например, CharField для символьных полей и DateTimeField для
datetime. Это сообщает Django, какой тип данных содержит
каждое поле.
* Имя каждого экземпляра Field (например, question_text или
pub_date) – это имя поля в машинно-удобном формате. Вы
будете использовать это значение в своем коде Python, а ваша
база данных будет использовать его в качестве имени столбца.
* Некоторые классы Field имеют обязательные аргументы.
CharField, например, требует, чтобы вы передали ему аргумент
max_length. Это используется не только в схеме базы данных,
но и при проверке

23. Создание моделей

*
* Вы можете использовать необязательный первый позиционный
аргумент для Field для обозначения понятного человеку
названия. Это используется в паре интроспективных частей
Django, и дублируется как документация. Если это поле не
указано, Django будет использовать машиночитаемое имя. В
этом примере мы определили только удобочитаемое имя для
Question.pub_date. Для всех других полей в этой модели,
машиночитаемое имя поля будет достаточно в качестве его
удобочитаемого имени.
* Field также может иметь различные необязательные аргументы.
В этом случае мы установили для default значение voice в 0.
* Наконец, обратите внимание, что связь определена с
использованием ForeignKey. Это говорит Django, что каждый
Choice связан с одним Question. Django поддерживает все
общие отношения базы данных: многие-к-одному, многие-комногим и один-к-одному.

24. Активация моделей

*
* Сначала нужно сообщить нашему проекту, что установлено
приложение polls.
* Чтобы включить приложение в проект, нужно добавить ссылку
на его класс конфигурации в настройке INSTALLED_APPS. Класс
PlayersConfig находится в файле polls/apps.py, поэтому его путь
- 'polls.apps.PollsConfig'. Отредактируйте файл mysite/settings.py
и добавьте этот путь в параметр INSTALLED_APPS. Это будет
выглядеть так:

25. Активация моделей

*
* Теперь Django знает, как подключить приложение polls.
Запустим команду:
* Запустив makemigrations, вы сообщаете Django, что внесли
некоторые изменения в свои модели (в данном случае сделали
новые) и хотите, чтобы изменения были сохранены как
* миграция*.

26. Создание SQL

*
* Миграции - это то, как Django хранит изменения в моделях (и,
следовательно, в схеме базы данных) - это файлы на диске. Вы
можете прочитать миграцию для своей новой модели, если
хотите. Это файл polls/migrations/0001_initial.py.
* Есть команда, которая будет запускать миграции и
автоматически управлять схемой базы данных - она называется
migrate.
* Какой SQL будет выполняться этой миграцией. Команда
sqlmigrate принимает имена миграции и возвращает их SQL
* python manage.py sqlmigrate polls 0001

27. Создание SQL

*

28. Создание SQL

*
* Точный вывод будет зависеть от базы данных, которую вы используете
* Имена таблиц автоматически генерируются путем объединения названия
приложения (polls) и названия модели в нижнем регистре - question и
choice.
* Первичные ключи (идентификаторы) добавляются автоматически.
* По соглашению, Django добавляет "_id" к имени поля внешнего ключа.
* Отношение внешнего ключа становится явным с помощью ограничения
FOREIGN KEY.
* Он адаптирован к используемой вами базе данных, поэтому
обрабатываются специфичные для базы данных типы полей, такие как
auto_increment (MySQL), serial (PostgreSQL) или integer primary key
autoincrement (SQLite) для вас автоматически. То же самое касается
экранирования имен полей - например, использование двойных или
одинарных кавычек.
* Команда sqlmigrate на самом деле не запускает миграцию в вашей базе
данных - она просто выводит ее на экран, чтобы вы могли увидеть, какой
SQL Django считает необходимым. Это полезно для проверки того, что
собирается делать Django, или если у вас есть администраторы баз
данных, которым требуются сценарии SQL для изменений.

29. Создание таблиц в БД

*
* Теперь запустите migrate еще раз, чтобы создать эти таблицы
моделей в вашей базе данных:

30. Команда migrate

*
* Команда migrate берет все миграции, которые не были применены
(Django отслеживает, какие из них применены, используя специальную
таблицу в базе данных под названием django_migrations) и запускает их в
базе данных - по сути, синхронизируя изменения, которые вы внесли в
свои модели с помощью схемы в базе данных.
* Миграции очень мощны и позволяют со временем менять свои модели по
мере разработки проекта, без необходимости удалять вашу базу данных
или таблицы и создавать новые - она специализируется на обновлении
вашей базы данных в реальном времени, без потери данных.
* 3 этапа создания моделей:
1) Изменение модели (models.py).
2) Запуск команды python manage.py makemigrations для создания
миграций этих изменений.
3) Выполнение команды python manage.py migrate для применения этих
изменений в базе данных.
* Причина того, что существуют отдельные команды для создания и
применения миграций, заключается в том, что вы фиксируете миграции в
своей системе контроля версий и отправляете их вместе с вашим
приложением; они не только облегчают вашу разработку, они также
могут использоваться другими разработчиками и в производстве.

31. API

*
* Аббревиатура API расшифровывается как «Application
Programming Interface» (интерфейс программирования
приложений, программный интерфейс приложения).
Большинство крупных компаний на определённом этапе
разрабатывают API для клиентов или для внутреннего
использования.
* Теперь давайте перейдем к интерактивной оболочке Python и
поиграемся с API, предоставляемым Django. Чтобы вызвать
оболочку Python, используйте эту команду:
* python manage.py shell
* На следующем слайде приведет пример: создание записи в
таблице Question, вывод на экран содержимого полей,
изменение поля и сохранение в БД.

32. API

*

33. API

*
* Выражение <Question: Question object (1)> не является
информативным и полезным. Поэтому давайте это исправим,
отредактировав модель Question (в файле polls/models.py) и
добавив метод __str__() в обе модели Question и Choice (см.
следующий слайд)
* Обратите внимание на добавление datetime и from django.utils
import timezone для ссылки на стандартный модуль Python
datetime и утилиты Django, связанные с часовыми поясами, в
django.utils.timezone соответственно.

34. API

*

35. API

*

36. API

*

37. Административная часть Django

*
* Создание сайтов администратора для ваших сотрудников или
клиентов для добавления, изменения и удаления контента - это
утомительная работа, которая не требует большого творческого
подхода. По этой причине Django полностью автоматизирует создание
интерфейса администратора моделей.
* Django был написан в новостной среде с очень четким разделением
между «создателями контента» и «публичным» сайтом. Менеджеры
сайтов используют систему для добавления новостей, событий,
спортивных результатов и т.п. И этот контент отображается на
общедоступном сайте.
* Django решает проблему создания единого интерфейса как для
администраторов сайтов, так и для редактирования контента.
* Администраторская часть не предназначена для использования
посетителями сайта.

38. Административная часть Django

*
* Сначала нам нужно создать пользователя, который сможет
войти на сайт администратора.

39. Вход в админку

*
* python manage.py runserver
* Откройте веб-браузер и перейдите по ссылке «/admin/» в
локальном домене - например, http://127.0.0.1:8000/admin/.

40. Вход в админку

*
* Вводим логин и пароль и мы в админке

41. Добавление своего приложения в админку

*
* Нужно сообщить админке, что у объектов Question есть
интерфейс администратора. Для этого откройте файл
polls/admin.py и отредактируйте его следующим образом

42. Добавление своего приложения в админку

*
* Изучите возможности админки самостоятельно

43. Представление

*
* Представление – это «тип» веб-страницы в приложении
Django, которая обычно выполняет определенную функцию и
имеет определенный шаблон. В нашем приложении для
опроса будут следующие четыре представления:
* Главная страница вопросов - отображает последние
несколько вопросов.
* Страница вопроса - отображает текст вопроса, без
результатов, но с формой для голосования.
* Страница результатов вопроса - отображает результаты для
конкретного вопроса.
* Голосования - обрабатывает голосование за определенный
выбор в конкретном вопросе.

44. Представление

*
* В Django веб-страницы и другой контент доставляются по
представлениям. Каждое представление представлено
функцией Python (или методом в случае представлений на
основе классов). Django выберет представление, изучив
запрашиваемый URL (точнее, часть URL после имени домена).
* Шаблон URL - это общая форма URL, например:
/newsarchive/<year>/<month>/.
* Чтобы перейти от URL к представлению, Django использует
так называемый URLconfs. URLconf сопоставляет шаблоны URL
с представлениями.

45. Представление

*
* Добавим еще несколько представлений в polls/views.py. Эти
представления немного отличаются, потому что они
принимают аргумент:

46. Представление

*
* Подключите эти новые представления в модуль polls.urls,
добавив следующие path() вызовы:
* Перейдите в браузере по адресу «/polls/34/». Он запустит
метод detail() и отобразит любой идентификатор, который вы
указали в URL. Попробуйте также «/polls/34/results/» и
«/polls/34/vote/» - они отобразят результаты и страницы
голосования.

47. Представление

*
* Когда кто-то запрашивает страницу с вашего сайта - скажем, «/polls/34/»,
Django загрузит модуль Python mysite.urls, поскольку на него указывает
параметр ROOT_URLCONF. Он находит переменную с именем `` urlpatterns`` и
просматривает шаблоны по порядку. После нахождения соответствия в 'polls/'
``, он убирает соответствующий текст («polls/») и отправляет оставшийся текст
- ``"34/" - в „polls.urls“ URLconf для дальнейшей обработки. Там он
соответствует '<int:question_id>/', что приводит к вызову представления detail()
следующим образом:
detail(request=<HttpRequest object>, question_id=34)
* Часть question_id=34 взята из <int:question_id>. Использование угловых скобок
«захватывает» часть URL и отправляет ее в качестве ключевого аргумента в
функцию представления. Часть строки :question_id> определяет имя, которое
будет использоваться для идентификации сопоставленного шаблона, а часть
<int: - это преобразователь, который определяет, какие шаблоны должны
соответствовать этой части пути URL.
* Нет необходимости добавлять в URL лишнее, например .html. Если же вы
захотите, в этом случае вы можете сделать что-то вроде этого:
path('polls/latest.html', views.index),
* Но не делайте этого. Это глупо.

48. Представления

*
* Каждое представление отвечает за выполнение одного из двух
действий: возвращение объекта HttpResponse, содержащего ответ
для запрашиваемой страницы, или создание исключения, такого
как Http404. Остальное зависит от вас.
* Ваше представление может читать записи из базы данных, или нет.
Оно может использовать систему шаблонов, такую как Django или
стороннюю систему шаблонов Python, или нет. Он может
генерировать PDF-файл, выводить XML, создавать ZIP-файл на лету,
что угодно, используя любые библиотеки Python, которые вы
хотите.
* Поскольку это удобно, давайте использовать собственное API базы
данных Django. Напишем другой вариант в представлении index(),
который будет отображать последние 5 вопросов, разделенных
запятыми, в соответствии с датой публикации.

49. Представления

*
* Отредактируем polls/views.py
* Получим

50. Шаблоны

*
* Однако есть проблема: дизайн страницы жестко закодирован в представлении.
Если вы хотите изменить внешний вид страницы, вам придется редактировать
этот используя Python. Однако есть решение. Давайте используем систему
шаблонов Django, чтобы отделить дизайн страницы от Python, создав шаблон,
который может использовать представление.
* Сначала создайте каталог с именем templates в каталоге polls. Джанго будет
искать там шаблоны.
* Параметр TEMPLATES вашего проекта описывает, как Django будет загружать и
отображать шаблоны. Файл настроек по умолчанию настраивает бэкэнд
DjangoTemplates, чья опция APP_DIRS установлена в `` True``. По соглашению
DjangoTemplates ищет подкаталог «templates» в каждом из INSTALLED_APPS.
* В каталоге templates, который вы только что создали, создайте еще один
каталог с именем polls, а внутри него создайте файл с именем index.html.
Другими словами, ваш шаблон должен быть в polls/templates/polls/index.html.
Из-за того, что загрузчик шаблонов app_directories работает так, как описано
выше, вы можете ссылаться на этот шаблон в Django просто как
polls/index.html.

51. Шаблоны

*
* polls/templates/polls/index.html

52. Шаблоны

*
* Изменим представление index в polls/views.py
* Этот код загружает шаблон с именем polls/index.html и передает
ему контекст. Контекст представляет собой словарь,
отображающий имена переменных шаблона в объекты Python.

53. Шаблоны

*
* Получим маркированный список,
содержащий вопросы

54. render()

*
* Это очень распространенный механизм: загрузить шаблон,
заполнить контекст и вернуть объект HttpResponse с результатом
визуализации шаблона.
* В Django есть другой механизм. Перепишем polls/views.py
следующим образом
* Функция render() принимает объект запроса в качестве первого
аргумента, имя шаблона в качестве второго аргумента и словарь в
качестве необязательного третьего аргумента. Она возвращает
объект HttpResponse данного шаблона, отображенный в данном
контексте.

55. Ошибка 404

*
* Теперь перепишем страницу, на которой отображается текст
вопроса для данного опроса следующим образом.
* Представление вызывает исключение Http404, если вопроса
с запрошенным идентификатором не существует.

56. Ошибка 404

*
* Создадим шаблон polls/templates/polls/detail.html и добавим
туда для примера только (для тестирования будет
достаточно):

57. get_object_or_404()

*
* Это очень распространенная практика использовать get() и
вызывать Http404, если объекта не существует. Вот
переписанное представление detail() в сокращенном виде:
* Функция get_object_or_404() принимает модель Django в
качестве первого аргумента и произвольное количество
ключевых аргументов, которое она передает в get() функцию менеджера модели. Она вызывает Http404, если
объект не существует.

58. get_object_or_404()

*
* Это очень распространенная практика использовать get() и
вызывать Http404, если объекта не существует. Вот
переписанное представление detail() в сокращенном виде:
* Функция get_object_or_404() принимает модель Django в
качестве первого аргумента и произвольное количество
ключевых аргументов, которое она передает в get() функцию менеджера модели. Она вызывает Http404, если
объект не существует.

59. get_object_or_404()

*
* Зачем мы использовали вспомогательную функцию
get_object_or_404() вместо того, чтобы автоматически
перехватывать исключения ObjectDoesNotExist на более
высоком уровне или вызывать через API модели Http404
вместо ObjectDoesNotExist?
* Такая реализация связывает уровень модели с уровнем
представления. Одна из главных целей Django поддерживать эту связь.
* Дополнительные контроли представлены в модуле
django.shortcuts.
* Есть функция get_list_or_404(), которая работает так же, как
get_object_or_404() - за исключением использования filter()
вместо get(). Она вызывает Http404, если список пуст.

60. Система шаблонов

*
* Вернемся к представлению detail() нашего приложения poll.
Учитывая переменную question, вот так можно переписать
шаблон polls/detail.html

61. Система шаблонов

*
* Система шаблонов использует синтаксис поиска точек для
доступа к переменным. В примере {{ question.question_text }}
сначала Django выполняет поиск в словаре по объекту
question. В противном случае он пытается найти атрибут,
который работает, в данном случае. Если поиск атрибута не
удался, он попытался бы выполнить поиск по индексу списка.
* Вызов метода происходит в цикле {% for %}.
question.choice_set.all интерпретируется как код Python
question.choice_set.all(), который возвращает итерацию
объектов Choice и подходит для использования в теге {% for
%}.

62. URL-адреса в шаблонах

*
* Когда мы писали ссылку на вопрос в шаблоне
polls/index.html, она была частично жестко закодирована
следующим образом:
* Проблема этой жесткой закодированности, заключается в
том, что становится сложно изменять URL-адреса в проектах
с большим количеством шаблонов. Однако, поскольку вы
определили аргумент name в функциях path() в модуле
polls.urls, вы можете удалить зависимость от конкретных
путей URL, определенных в ваших конфигурациях URL, с
помощью шаблонного тега {% url %}:

63. URL-адреса в шаблонах

*
* Сейчас в polls/urls.py:
* Если вы хотите изменить URL-адрес подробного
представления опросов на что-то другое, возможно, на что-то
вроде polls/specifics/12/, то вместо того, чтобы делать это в
шаблоне (или шаблонах), вы должны изменить его в
polls/urls.py:

64. Пространство имен URL

*
* У нашего проекта есть только одно приложение: polls. В
реальных проектах Django может быть пять, десять, двадцать
приложений или больше. Как Django различает имена URL
между ними? Например, приложение polls имеет
представление detail, как и приложение в том же проекте,
что и для блога. Как сделать так, чтобы Django знал, какое
представление приложения создавать для URL при
использовании тега шаблона {% url %}?
* Ответ заключается в том, чтобы добавить пространство имен
в ваш URLconf. В файле polls/urls.py добавьте app_name для
установки пространства имен приложения:

65. Пространство имен URL

*
* Для указания на пространство имен
polls/templates/polls/index.html¶

66. Минимальная форма

*
* Обновим шаблон опроса (polls/templates/polls/detail.html),
чтобы шаблон содержал HTML-тэг <form>:

67. Минимальная форма

*
* Приведенный выше шаблон отображает кнопку для каждого вопроса.
Значение value каждой кнопки является идентификатором (ID)
соответствующего вопроса. Имя name каждой радиокнопки - это
"choice". Это означает, что когда кто-то выбирает один из
переключателей и отправляет форму, он отправляет POST-данные
choice=# где # - идентификатор выбранного варианта. Это основная
концепция форм HTML.
* Мы устанавливаем action формы в {% url 'polls: voice' question.id %} и
устанавливаем method="post". Использование method="post" ` (в
отличие от ``method="get") очень важно, потому что отправка этой
формы изменит данные на стороне сервера. Всякий раз, когда вы
создаете форму, которая изменяет данные на стороне сервера,
используйте method="post". Этот совет не относится только к Django;
Это хорошая практика веб-разработки в целом.
* forloop.counter указывает, сколько раз тег for прошел цикл
* Поскольку мы создаем форму POST (которая может повлиять на
изменение данных), нам нужно беспокоиться о подделках
межсайтовых запросов. К счастью, вам не нужно слишком сильно
беспокоиться, потому что Django поставляется с полезной системой
для защиты от него. Короче говоря, все формы POST, предназначенные
для внутренних URL-адресов, должны использовать тег шаблона {%
csrf_token %}.

68. Минимальная форма

*
* Добавим в polls/views.py:

69. Минимальная форма

*
* request.POST представляет собой объект, подобный словарю, который позволяет получить
доступ к отправленным данным по ключу. В этом случае request.POST ['choice'] возвращает
идентификатор выбранного варианта в виде строки. Значения request.POST всегда
являются строками.
* Обратите внимание, что Django также предоставляет request.GET для доступа к данным
GET таким же образом, но мы явно используем request.POST в нашем коде, чтобы
гарантировать, что данные изменяются только через вызов POST.
* request.POST ['choice'] будет вызывать KeyError, если ключ choice не был предоставлен в
POST. Приведенный выше код проверяет KeyError и повторно отображает форму вопроса с
сообщением об ошибке, если choice не задано.
* После увеличения счетчика выбора код возвращает HttpResponseRedirect, а не обычный
HttpResponse. HttpResponseRedirect принимает один аргумент: URL-адрес, на который
будет перенаправлен пользователь.
* Как указано выше в комментарии Python, вы должны всегда возвращать
HttpResponseRedirect после успешной обработки данных POST. Этот совет не относится
только к Django; Это хорошая практика веб-разработки в целом.
* В этом примере мы используем функцию reverse() в конструкторе HttpResponseRedirect.
Эта функция помогает избежать жесткого кодирования URL-адреса в функции
представления. Ему дается имя представления, которому мы хотим передать управление,
и переменная часть шаблона URL, которая указывает на это представление. В этом
случае, используя URLconf, который мы настроили ранее, вызов reverse() вернет строку,
подобную
* '/polls/3/results/'
* где 3 - это значение question.id. Этот перенаправленный URL-адрес затем вызовет
представление 'results', чтобы отобразить последнюю страницу.

70. Минимальная форма

*
* После того, как кто-то проголосовал в опросе, представление
voice() перенаправляет на страницу результатов для опроса.
Давайте напишем это представление:

71. Минимальная форма

*
* Теперь создадим шаблон polls/templates/polls/results.html
* Теперь перейдите к /polls/1/ в вашем браузере и
проголосуйте в опросе. Вы должны увидеть страницу
результатов, которая обновляется каждый раз, когда вы
голосуете. Если вы отправляете форму, не выбрав вариант,
вы должны увидеть сообщение об ошибке.
English     Русский Правила