Задание. Модель данных для библиотеки
Создадим модель данных для веб-приложения «Библиотека».
Постановка задачи
Допустим, что мы разрабатываем веб-приложение для автоматизации работы небольшой библиотеки (той, где книги выдают). Вам поручено разработать модель данных для этого приложения.
Сущности
Требуется создать следующие сущности (далее перечислены сущности с их полями):
Читатель (Reader)
- Фамилия (
last_name
) - Имя (
first_name
)
Писатель (Author)
- Фамилия (
last_name
) - Имя (
first_name
)
Книга (Book)
- Название (
title
) - Аннотация (
annotation
) - Автор (
author
) – это поле должно быть отношением многие-к-одному с моделью «Писатель»
Выдача (Borrowing)
- Книга (
book
) – отношение многие-к-одному с моделью «Книга» - Читатель (
reader
) – отношение многие-к-одному с моделью «Читатель» - Дата выдачи (
borrow_date
) - Дата возврата (
return_date
) - Вернулась ли книга (
was_returned
) — True, если книга была возвращена, в противном случае False
Изображение схемы данных (полный размер):
Общее описание логики
Основная сущность — Книга. У книги есть Автор, вынесенный в качестве отдельной сущности в целях нормализации модели данных (уменьшение дублирования информации). Кроме того, есть список зарегистрированных в библиотеке Читателей.
Когда книга выдаётся на руки читателю, добавляется новый объект Выдача. В выдачу записывается, соответственно, книга, которую выдали, читатель, который получил книгу, а так же дата выдачи и крайняя дата возврата книги. Кроме того, в поле «Вернулась ли книга» заносится False (что логично).
Когда читатель возвращает книгу, в соответствующем объекте Выдача в поле «Вернулась ли книга» заносится True.
Обратите внимание, что объекты модели Выдача никогда не удаляются — библиотека хранит историю выдачи каждой книги.
Дополнительные функции модели Книга
В модель «Книга» нужно добавть следующие методы.
Выдана ли книга? (is_borrowed)
def is_borrowed()
Этот метод должен проверить, есть ли соответствующая книге сущность «Выдача», у которой в поле «Вернулась ли книга» хранится False. Если такая сущность есть, этот метод должен вернуть значение True
, в противном случае — False
. То есть, используя этот метод, мы можем узнать, выдана ли книга читателю, или находится в библиотеке.
Выдать книгу (borrow)
def borrow(reader, time=timedelta(days=14))
# По умолчанию выдаём на 14 дней
Этот метод должен проверить, не выдана ли книга уже. Если она уже выдана, метод просто возвращает False
, так как повторно выдать книгу нельзя. Если книга не выдана, этот метод создаёт новый объект «Выдача», заполняет его (в качестве даты выдачи берётся сегодняшняя дата, в качестве даты возврата берётся сегодняшняя дата плюс указанный в параметре time
промежуток времени, по умолчанию 14 дней) и сохраняет, после чего возвращает True
.
То есть результат этого метода: False
, если книга уже выдана, и True
, если всё в порядке и книгу можно выдать на руки читателю.
Вернуть книгу (return_to_library)
def return_to_library()
Этот метод находит соответствующий книге объект «Выдача», у которого в поле «Вернулась ли книга» значение False
, и, если он есть, меняет значение этого поля на True
, то есть возвращает книгу в библиотеку. Метод возвращает True
, если книга вернулась (то есть был найден и изменён соответствующий объект «Выдача»), либо False
, если книга и так уже в библиотеке (то есть соответствующая выдача не найдена).
Дополнительные функции модели Читатель
В модель Читатель нужно добавить следующие методы.
Книги на руках (borrowed_books)
def borrowed_books()
Метод возвращает список (а лучше — QuerySet
) из объектов Книга, выданных читателю. Книга выдана читателю, если существует объект Выдача для этого читателя, у которого в поле «Вернулась ли книга» хранится значение False
. Проще говоря, метод возвращает список книг, которые читатель взял и пока что не вернул.
Просроченные книги (overdue_books)
def overdue_books()
Метод возвращает список (а лучше — QuerySet
) книг, которые читатель не вернул в срок. То есть почти то же самое, что и предыдущий метод, но дополнительное условие: в объекте Выдача для книги дата возврата раньше, чем сегодняшняя дата.
Замечания по реализации
Постарайтесь не делать лишних запросов. Кроме того, в методах, которые ищут книги (методы модели Читатель) нужно подумать, от какой из наших моделей начинать поиск — от Книги или от Выдачи.
Кроме того, не забудьте импортировать классы date
и timedelta
из модуля datetime
.