📝 Практикум 1: Django Models — 15 задач

Library Project: построение схемы БД шаг за шагом

⚡ Все 15 задач — кратко

  1. Author: first_name, last_name, birth_date → Admin + migrate
  2. Author: + profile (URLField), deleted (Bool), rating (Int 1–10)
  3. Author: verbose_name для всех полей + help_text для deleted
  4. Book: title, author_id (FK SET_NULL), publishing_date
  5. Book: + summary (TextField), genre (choices), page_count (max 10000)
  6. Publisher: name, address, city, country; Book.publisher_id (FK)
  7. Category: name (unique); Book.category (FK SET_NULL, related_name='books')
  8. Library: name, location, site; Book.libraries (M2M, related_name='books')
  9. Member: email, gender, age, role, active, libraries (M2M); убрать Publisher
  10. Posts: title (unique_for_date), body, author, moderated, library, dates
  11. Borrow: member, book, library, borrow_date, return_date, returned + is_overdue()
  12. Review: book, reviewer, rating (Float), description; Book.rating (property)
  13. AuthorDetail: author (OneToOne), biography, birth_city, gender
  14. __str__ для всех моделей
  15. Event + EventParticipant: система событий в библиотеке

Решения →

К нам пришел заказчик с идеей создать свою систему библиотек, в которой всем можно было бы выкладывать разных авторов, их книги, читать биографию авторов и ставить свои отзывы. Нам необходимо разработать такое приложение — начнём с базы данных.

Блок 1: Модель Author

Задание 1

Создайте Django проект и добавьте новое приложение library. В этом приложении создайте модель Author со следующими полями:

  • Имя: макс. длина 100
  • Фамилия: макс. длина 100
  • Дата рождения

Зарегистрируйте эту модель для Административной панели, примените изменения и убедитесь, что всё работает корректно.

Задание 2

В процессе разработки мы поняли, что для автора необходимы ещё некоторые поля для хранения дополнительной информации.

Обновите уже существующую модель Author дополнительными полями:

  • Профиль: ссылка на личную страницу автора, может быть не указана
  • Удалён: поле, которое позволит смотреть, удалён ли этот автор из базы всех авторов. По умолчанию все авторы активны
  • Рейтинг: позволит отсматривать рейтинг популярности авторов, от 1 до 10

Задание 3

Заказчик решил, что в административной панели ему очень неудобно ориентироваться по названиям полей в таблице Авторов. Но если мы напрямую поменяем все поля — это приведёт к значительным изменениям в базе данных и проекте.

Обновите настройки модели так, чтобы заказчику было удобно работать в Административной панели, а база данных осталась нетронутой. Также заказчик не особо понял поле deleted. Обновите это поле, добавив для него подсказку, как пользоваться этим параметром.

Блок 2: Модель Book

Задание 4

С автором мы закончили, и нам тут же пришла новая задача на создание модели для книг — одна из самых важных моделей в нашем приложении библиотеки.

Создайте модель Book со следующими полями:

  • Имя книги: обязательно к заполнению
  • Ссылка на автора: при удалении автора книги пропасть не должны
  • Дата публикации

Свяжите новую модель книги с автором. У одного автора может быть много книг.

Задание 5

Наш senior посмотрел на модель, что мы создали, и предложил внести некоторые правки по улучшению модели.

В модель Book добавьте дополнительные поля для большей информации о книге:

  • Краткое описание: TextField, может быть пустым
  • Жанр: CharField, макс. длина 50, выборы из ['Fiction', 'Non-Fiction', 'Science Fiction', 'Fantasy', 'Mystery', 'Biography']
  • Кол-во страниц: может быть пустым, максимальное кол-во — 10000

Примените изменения в модели, попробуйте создать записи, не указывая некоторые поля. Обратите внимание на то, как отрабатывает система.

Блок 3: Publisher, Category, Library

Задание 6

На daily созвоне вы определились, что в приложении также будет специальная модель Публикатора, которая будет отвечать за информацию о том, кто выложил новую книгу. Задача досталась вам.

Создайте модель Publisher со следующими полями:

  • Имя: макс. длина 100
  • Адрес: макс. длина 255, может быть пустым
  • Город: макс. длина 100, может быть пустым
  • Страна: макс. длина 100

Добавьте новое поле публикатора в модель Book как ForeignKey, связь с моделью Publisher.

Задание 7

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

Создайте модель Category для хранения категорий книг. Модель будет содержать поля:

  • Имя категории: макс. длина 30, категории должны быть уникальны

Свяжите модель Category с моделью Book с помощью связи «один ко многим».

  • У книги должна быть возможность получить сведения о категории по «относящемуся имени».
  • Одна категория может быть у многих различных книг. Каждая книга может состоять только в одной категории (для примера: Книга из категории «Для размышлений», жанр — «Психологический детектив»).

Задание 8

Мы успешно закрыли много задач по созданию структуры базы данных, но расслабляться ещё рано! Теперь нам доверили задачу на создание модели библиотеки, которая будет связывать книги, авторов и читателей этой библиотеки.

Создайте модель Library, представляющую библиотеки, которые могут содержать множество книг. Модель будет состоять из полей:

  • Название библиотеки: макс. длина 100
  • Локация этой библиотеки: макс. длина 200
  • Сайт библиотеки: содержит ссылку, у библиотеки может не быть своего сайта
  1. Свяжите модель Library с моделью Book с помощью связи «многие ко многим».
  2. Должны быть «смежные» поля, по которым у книги можно получить список библиотек, где эта книга есть, а у библиотеки можно получить список книг, какие она имеет у себя.

Блок 4: Member, Posts, Borrow

Задание 9

На очередном созвоне вашим коллегой была предложена идея по созданию общей модели Member, в которой могут быть и обычные читатели, и модераторы, и администраторы. Эта идея очень понравилась и заказчику, и команде, а старую модель Publisher было решено удалить.

Создайте модель Member, представляющую членов библиотеки. В этой модели должны быть поля:

  • Имя: макс. длина 50
  • Фамилия: макс. длина 50
  • Емэйл: уникальный
  • Гендер: строковое поле, возможность выбора из уже существующих гендеров
  • Дата рождения
  • Возраст: в пределах от 6 до 120 лет
  • Роль: строковое поле с возможностью выбора ролей «Админ», «сотрудник», «читатель»
  • Активный: логическое поле, по умолчанию при создании пользователя он активный
  • Библиотеки: связь с моделью Library. Пользователь может быть во многих библиотеках, должно быть связующее поле
  1. Таблица Publisher больше не нужна, удалите её, так как будет новая таблица Member, в которой можно выбрать роль стафа — сотрудники, которые и будут публиковать новые книги разных авторов.
  2. В поле publisher_id переделайте связь на новую модель.
  3. Убедитесь, что у вас не будет ошибок, которые могут быть связаны с отсутствием записи члена библиотеки, который должен быть указан для конкретной книги.

Задание 10

Рабочая неделя началась с новой задачи! Нам дали задачу на реализацию системы постов, чтобы каждая библиотека могла публиковать посты, они могут быть от администратора, модератора. Более того, было решено, что оглавление поста должно быть уникальным в рамках создания такого поста, чтобы не было ничего повторяющегося.

Создайте модель Posts с полями:

  • Оглавление поста: до 255 символов, оглавление должно быть уникальным в рамках даты создания
  • Текст Поста: объёмный текст
  • Автор: ссылка на члена библиотеки, один автор может написать много постов
  • Промодерировано: по умолчанию ничего не промодерировано
  • Библиотека: связь к библиотеке. В каждой библиотеке может быть много своих постов
  • Дата создания: заполняется при создании мануально
  • Дата обновления: заполняется автоматически

Задание 11

Заказчик попросил добавить возможность отслеживания книг. Кто, когда, что и где взял. Эта задача после очередного митинга улетела к вам, так как вы с таким уже работали.

Создайте модель Borrow для отслеживания книг, взятых членами библиотеки.

  • Участник: связь с моделью Member
  • Книга: связь с моделью Book
  • Библиотека: связь с моделью Library
  • Дата взятия книги: когда читатель взял книгу
  • Дата возврата: когда книга должна быть возвращена
  • Вернул ли книгу: логическое поле

Допишите метод, который будет проверять, просрочил ли читатель срок сдачи книги.

Блок 5: Review, AuthorDetail, __str__, Events

Задание 12

Только мы закрыли предыдущую задачу — пришла новая от нашего менеджера проекта. От нас хотят, чтобы мы продумали логику создания отзывов для книг. Более того, нужно будет также внедрить в отзывы и проставление среднего рейтинга, который должен рассчитываться для каждой книги на основе всех отзывов.

Создайте модель Review для хранения отзывов о книгах с полями:

  • Книга (связь с моделью Book)
  • Обзорщик (связь с моделью Member)
  • Рейтинг (от 1 до 5, рейтинг может быть дробным)
  • Отзыв (большое текстовое поле)
  1. Объедините модель Review с моделями книг (модель Book) и читателей (модель Member).
  2. Добавьте к модели Book property-поле rating, которое будет автоматически высчитывать среднюю оценку книги по её рейтингам в отзывах.

Задание 13

Нас попросили расширить информацию об авторе, но чтобы не переделывать таблицу Author, наш senior предложил нам создать таблицу с деталями об авторе, которая будет идти в отношении «один к одному».

Создайте модель AuthorDetail для хранения дополнительных данных об авторах.

  • Автор: связь с моделью Author
  • Биография: Большое текстовое поле
  • Город рождения: необязательное
  • Гендер: поле с выбором из существующих гендеров

Задание 14

В проекте стало слишком много моделей, данных и информации в целом. Стандартный вывод этих данных в административной панели перестал быть простым.

Для всех моделей, что вы создали, организуйте более явное отображение данных, чёткое, структурированное для каждой модели. Например, при просмотре данных об авторах в административной панели должны отображаться их имя и инициал фамилии.

Задание 15

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

  1. Создайте систему для отслеживания событий, проводимых в библиотеке, включая модели для участников событий и записей на события.
  2. Свяжите эти модели с уже существующими моделями Member, Library и Book.

Модель Event:

  • Название события: макс. длина 255
  • Описание события: большое текстовое поле
  • Дата проведения события: и дата, и время
  • Библиотека, в которой проводится событие (связь с моделью Library)
  • Книги, которые будут обсуждаться на событии (связь с моделью Book)

Модель EventParticipant:

  • Событие, на которое зарегистрирован участник (связь с моделью Event)
  • Участник события: связь с моделью Member
  • Дата регистрации на событие: дата по умолчанию подставляется текущего дня