Практически всю веб-разработку можно свести к CRUD-операциям. CRUD — широко распространенный термин, который означает четыре стандартные операции над любой сущностью. В этом уроке познакомимся с CRUD-операциями, которые считаются типичными для веб-разработки.
Операции CRUD
CRUD — это акроним, который обозначает четыре операции над сущностями веб-разработки по первым буквам их названий:
- Create — создание
- Read — чтение
- Update — обновление
- Delete — удаление
Например, в случае с пользователем можно составить такое соответствие:
Create
- Регистрация
Read
- Просмотр профиля пользователями сайта
- Просмотр пользователя в административном интерфейсе
Update
- Обновление личных данных
- Смена емейла
- Смена пароля
Delete
- Удаление
Так же можно расписать действия над любыми другими ресурсами: фотографиями пользователя, его друзьями, сообщениями.
Создание полного круда включает в себя следующие действия:
- Создание сущности в коде
- Добавление таблицы в базу
- Написание тестов на обработчики
- Добавление обработчиков
- Добавление шаблонов
Новички тратят на создание такого круда не один день. У опытного разработчика в прокачанном фреймворке этот процесс занимает максимум часы. Flask, как и другие микрофреймворки, не предоставляет средств автоматизации, поэтому придется многое делать руками. В целях обучения это оправданно, но в промышленной разработке, это должно быть автоматизировано.
Дальше мы разберем весь процесс создания круда на примере каталога школ программирования за исключением работы с базой данных и тестов. Начнем с роутинга. Полный круд включает минимум семь маршрутов. Их может быть больше, так как любое из действий может повторяться не один раз:
Метод | Маршрут | Шаблон | Описание |
---|---|---|---|
GET | /schools | schools/index.html | Список школ |
GET | /schools/{id} | schools/show.html | Информация о школе |
GET | /schools/new | schools/new.html | Форма создания новой школы |
POST | /schools | Создание новой школы | |
GET | /schools/{id}/edit | schools/edit.html | Форма редактирования школы |
PATCH/PUT | /schools/{id} | Обновление школы | |
DELETE | /schools/{id} | Удаление школы |
Такое соглашение изначально появилось в Rails и затем было адаптировано во многих фреймворках на языках отличных от Ruby.
В этом уроке мы разберем первые два маршрута: просмотр списка и конкретного ресурса. Остальные рассмотрим в следующих уроках.
Нейминг
В Flask, как в микрофреймворке, нет строгих правил по именованию обработчиков. В других же более автоматизированных фреймворках заготовки обработчиков могут и вовсе создаваться сами.
В этом курсе мы будем придерживаться ресурсного наименования обработчиков. То есть название обработчика будет состоять из множественного имени сущности (users
, courses
) и действия (index
, show
, post
).
К примеру, обработчик, выводящий список пользователей, будет users_index()
, а выводящий конкретного пользователя - users_show()
.
Список (index)
Общий алгоритм вывода списка всегда проходит по одному сценарию и не зависит от языка программирования:
- Извлекаем список из базы данных. Обычно с учетом пейджинга
- Передаем данные в шаблон
- Выводим данные в шаблоне, используя цикл
Обычно в этот список добавляют различные действия, которые можно выполнять над сущностями. Например, редактирование, удаление или просмотр.
Обработчик
@app.route("/schools")
def schools_index():
repo = SchoolRepository()
schools = repo.content()
return render_template(
"schools/index.html",
schools=schools,
)
Шаблон
<table>
{% for school in schools %}
<tr>
<td>
{{ school.id }}
</td>
<td>
<a href="{{ url_for('schools_show', id=school.id) }}">{{ school.name }}</a>
</td>
</tr>
{% endfor %}
</table>
Отображение (show)
Это страница, на которой описана конкретная сущность. Например, на Хекслете к таким страницам относятся: профиль пользователя, страница курса, страница профессии, страница урока. Как и в случае со списком, порядок действий для отображения всегда один и тот же:
- Из адреса извлекается идентификатор сущности
- Выполняется поиск сущности в хранилище
- Она передается в шаблон
- В шаблоне рисуется красивый вывод
Обработчик
@app.route("/schools/<id>")
def schools_show(id):
repo = SchoolRepository()
school = repo.find(id)
return render_template(
"schools/show.html",
school=school,
)
Шаблон
<div>
{{ school.id }}: {{ school.name }}
</div>
Если сущность была удалена или ее вообще не существовало, то с точки зрения HTTP такой адрес сайта должен вернуть HTTP-код 404. Правильным способом будет использовать функцию abort
- она сгенерирует указанную ошибку. Если в нашем приложении также есть обработчки ошибок, то он выведет шаблон на перехваченную ошибку:
@app.route("/schools/<id>")
def schools_show(id):
repo = SchoolRepository()
school = repo.find(id)
if not school:
abort(404)
return render_template(
"schools/show.html",
school=school,
)
@app.errorhandler(404)
def not_found(error):
return "Oops!", 404
Заключение
Мы познакомились с CRUD-операциями, которые считаются типичными для веб-разработки: создание, чтение, обновление и удаление. Также мы подробно разобрали первые два маршрута: просмотр списка и конкретного ресурса. Далее рассмотрим остальные.
Самостоятельная работа
- Приведите маршруты и их имена в соответствии с указанной выше схемой
- Переделайте получение пользователей так, чтобы данные о пользователях брались из файла
Эталонное приложение
Дополнительные материалы
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.