Процесс создания круда пользователя включает минимум семь маршрутов. Два из них — просмотр списка и конкретного ресурса — мы уже разобрали. В этом уроке разберем следующие два, которые относятся к созданию сущности.
Создание сущности
Создание сущности подразумевает работу с модифицирующей формой, и как мы знаем, включает в себя два действия: отображение формы и обработка данных формы. За каждое из этих действий отвечает свой маршрут. Вот несколько примеров:
Пользователь
- GET
/users/new
- POST
/users
Курс
- GET
/courses/new
- POST
/courses
Сотрудник компании (пример вложенного маршрута)
- GET
/companies/3/users/new
- POST
/companies/3/users
Разберем каждое действие подробнее.
Отображение формы
Обработчик
@app.route("/schools/new")
def schools_new():
school = []
errors = []
return render_template(
"schools/new.html",
school=school,
errors=errors,
)
Шаблон
<!-- schools/new.html -->
<form action="/schools" method="post">
<div>
<label>
Название *
<input type="text" name="name" value="{{ school.name|default('', true) }}">
</label>
{% if errors %}
<div>{{ errors.name }}</div>
{% endif %}
</div>
<input type="submit" value="Create">
</form>
Содержимое обработчика сильно зависит от того, какой используется инструментарий. Если мы применяем билдеры формы, то обработчик создает форму как объект и отправляет его в шаблон. Билдер берет на себя огромное количество задач: обрабатывает вывод ошибок, занимается валидацией и подготовкой данных.
Особо умные билдеры знают про ту сущность, с которой они работают, и могут строить формы в полностью автоматическом режиме.
В нашем примере такого нет, поэтому все действия делаются руками. В форму мы передаем пустые данные, так как еще ничего не введено пользователем. Кроме данных в шаблон передается список errors
. Это нужно, так как форма в шаблоне будет использоваться двумя обработчиками: одним только для отображения новой формы, другим — для отображения формы в случае наличия ошибок.
Обработка данных формы
@app.post("/schools")
def schools_post():
repo = SchoolRepository()
# Извлекаем данные формы
data = request.form.to_dict()
# Проверяем корректность данных
errors = validate(data)
if errors:
# Если возникли ошибки, то устанавливаем код ответа в 422 и рендерим форму с указанием ошибок
return render_template("schools/new.html", school=data, errors=errors), 422
# Если данные корректны, то сохраняем, добавляем флеш и выполняем редирект
repo.save(data)
flash("School has been created", "success")
# Обратите внимание на использование именованного роутинга
return redirect(url_for("schools_index"))
Обработка формы нам уже знакома - извлекаем данные и валидируем. Если данные корректны, то выполняется основная логика обработчика – происходит сохранение школы в базу данных repo.save(data)
, а затем редирект на список школ с оповещением через флеш об успешном добавлении.
Если данные оказались не валидны, то этот обработчик рисует форму обработчика new
со всеми его введенными данными (чтобы пользователю не пришлось вновь их вводить) и ошибками. Затем отправляет ее вместе с кодом ответа 422 — Unprocessable Entity.
На этом создание сущности заканчивается. Следующим шагом научимся ее обновлять.
Самостоятельная работа
- Реализуйте обработку введенных данных и рендеринг формы с выводом ошибок
Эталонное приложение
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.