Язык программирования Python

Курс IT-Академии Сухорукова

Январь-март 2019

Этот курс закончился

Задание. Модель данных для библиотеки

Создадим модель данных для веб-приложения «Библиотека».

Постановка задачи

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

Сущности

Требуется создать следующие сущности (далее перечислены сущности с их полями):

Читатель (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.