Данная статья описывает домашнее задание 17 модуля, курса python_advanced.
Цели практической работы
- Попрактиковаться в реализации REST API с помощью модуля Flask-RESTful (или Flask-RESTX по желанию).
- Научиться сериализовывать и валидировать JSON с помощью модуля marshmallow.
Задача 1. Обновление структуры БД
- Примените знания, полученные в предыдущем модуле.
Сейчас в базе данных автор хранится как строковое поле в модели книги. Это может привести к аномалиям данных. Например, А. С. Пушкин и Александр Сергеевич Пушкин — один и тот же автор, но в базе эти имена будут храниться как два разных автора. - Создайте отдельную сущность «Автор», чтобы избежать этого. В ней должны быть следующие поля:id — первичный ключ;
first_name — имя автора;
last_name — фамилия автора;
middle_name — отчество автора (необязательно).
Так книга будет хранить не строковое представление автора, а внешний ключ на сущность.
В лекциях было рассказано о том как сделать базу данных с одной таблицей - books, в которой есть следующие поля:
id, title, author
Которые имеют вот такой вид:
Нужно сделать так чтобы поле author было уже не TEXT а INTEGER, и ссылалось на id-автора книги, которые будут записаны в другую таблицу (authors) со связью one-to-many (у одного автора может быть множество книг).
Соответственно нужен эндпойнт для вывода всех авторов, и для добавления новых авторов.
Я начал с того что создал дополнительную инициализацию базы данных, в которой сначала создаются авторы а потом, по ходу действия - книги.
Итак, файл models.py
Далее мы создаем базу данных, проверяем наличие таблицы с авторами и при её отсутствии создаем эту таблицу, наполняем ее нашими данными. Тоже самое делаем с таблицей "books".
Создаем новый класс Author:
Далее добавляем новые функции которые будут отвечать за выдачу по запросу GET списки книг или авторов:
Далее нам потребуется создать схему AuthorSchema(Schema)
Вроде бы ничего не забыл, осталось описать новый эндпойнт по получению списка авторов и добавлению новых:
Можно запустить программу и проверить как всё работает:
Попробуем добавить нового автора и книгу:
Ну и создадим книжку, последнего созданного автора (Сергея Есенина):
Ну вот, кажется всё, первое задание выполнено, переходим ко второму...
Задача 2. Создание REST API для работы с книгами
Реализуйте класс ресурса «Книга» и добавьте следующие методы:
PUT /api/books/{id} — изменение книги;
GET /api/books/{id} — получение информации о книге;
DELETE /api/books/{id} — удаление книги.
Советы и рекомендации
В видео мы рассматривали применение Flask-RESTful, но вы можете использовать более продвинутую версию этой библиотеки — Flask-RESTX. Разработчики активно поддерживают её, с ней можно быстро и удобно создавать сервисы REST API.
Также существует метод PATCH, который частично изменяет ресурс. Если PUT изменяет объект полностью и требует наличия всех обязательных полей, то PATCH изменяет только переданные поля. Попробуйте реализовать и его.
Что оценивается:
Есть валидация ID автора.
Все endpoints работают корректно, взаимодействуя с БД.
Начну я, пожалуй, с "GET /api/books/{id} — получение информации о книге", ибо GET это наиболее простой эндпойнт. И да, буду реализовывать с помощью библиотеки flask_restx, flask_restful пока на всякий случай закомментировал...
Собственно, с получением книги проблем не возникло, функция получения книги уже описана в models.py, так что вот так вот:
При обращении к энпойнту с соответствующим id-книги, мы её получаем:
Чтобы реализовать метод PUT в HTTP-запросе, для этого нужно:
Но я хотел реализовать так же и метод PATCH... И вот что у меня получилось, собственно всё 2е задание:
Я не понял, для чего было в советах и рекомендациях поведано о модуле flask_restx, чем он кардинально отличается от flask_restful... Как по мне, дак - тоже самое...
Задача 3. Создание REST API для работы с авторами
Создайте класс ресурса «Автор» и добавьте следующие методы:
POST /api/authors/ — создание автора;
GET /api/authors/{id} — просмотр всех книг автора;
DELETE /api/authors/{id} — удаление автора вместе со всеми его книгами.
Также реализуйте возможность создания автора при добавлении новой книги. Не забудьте указать все необходимые поля.
Как оказалось, что создание автора я уже сделал в первой части своего повествования (логично ж было создавать автора при создании книги).
Значит осталось сделать просмотр всех книг автора и его удаление (так как у нас таблица с авторами создавалась с параметром ON DELETE CASCADE, то и книги этого автора должны удаляться автоматически. Собственно с этого эндопойнта я и начну решение этой части задания.
Начнем с описания модели удаления автора, по аналогии с удалением книги:
Затем, собственно, создадим эндпойнт, который будет отвечать за удаление автора, он же будет выдавать информацию о книгах автора.
Вот вроде де бы с удалением автора, должны удаляться и записи с его книгами, но этого не произошло... Автор успешно удаляется а его книги остаются в БД. Значит где-то накосячил, буду искать где.
В лекциях было сказано, что для каскадного удаления, надо добавить строку:
Но мне это не помогло, после удаления автора, книги так же оставались на месте. Я было уже хотел выключить компуктер и лечь спать но вспомнил о телеграмм канале курса и нашел там это:
После чего всё заработало как надоть, книги удаляются вместе с автором! Осталось одно, вывести список книг автора. Думаю большой сложности в этом нет. Получаем id автора, и делаем запрос исходя из этого айди. Почти как все книги.
Начнем с models.py:
Ну и собственно отработка этой функции в эндпойнте:
Вроде бы все условия домашней работы соблюдены, можно и куратору показать... Хотя там остались две неиспользованных функции в models.py
Но в условиях задачи про них сказано не было...