Создание Book и BookCover должно быть атомарным, иначе ошибка оставит частично созданную книгу. Также не меняйте входной data, валидируйте обложки и возвращайте созданную книгу.
Добавление книги и её обложек через API
Создание Book и BookCover должно быть атомарным, иначе ошибка оставит частично созданную книгу. Также не меняйте входной data, валидируйте обложки и возвращайте созданную книгу.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
При выполнении POST‑запроса для создания новой книги вызывается функция create_book, которая формирует запись в таблице Book, а затем создает связанные записи в таблице BookCover.
Требуется провести ревью кода: проверить корректность и надёжность процесса создания сущностей, обратить внимание на возможные проблемы с атомарностью операций, обработкой исключений и потенциальными оптимизациями.
def create_book(data: dict):
cover_list: list[dict] = data.pop('covers')
new_book = Book.objects.create(**data)
for cover in cover_list:
BookCover.objects.create(**cover, book_id=new_book.id)
Ответ
Создание Book и BookCover должно быть атомарным, иначе ошибка оставит частично созданную книгу. Также не меняйте входной data, валидируйте обложки и возвращайте созданную книгу.
Порядок действий: проверить данные, скопировать data, извлечь covers, открыть transaction.atomic(), создать книгу и обложки, вернуть книгу. book_id задаётся сервером и не должен приниматься внутри cover от клиента.
Не подавляйте IntegrityError внутри сломанной транзакции; обработайте исключение снаружи atomic и сформируйте понятную ошибку API. Для многочисленных обложек возможен bulk_create, если не нужны индивидуальные save и сигналы. Файлы во внешнем хранилище не откатываются вместе с БД. При повторе POST нужна отдельная идемпотентность, если дубли книг недопустимы.