Модели
Нам необходимо описать БД средствами Django ORM, для этого перейдём в файл models.py
в нашем приложении и
создадим несколько классов, наследуемых от django.db.models.Model
.
Также внутри каждого класса создадим мета-класс с 3 полями:
db_table
- название таблицы в БД;verbose_name
- человекочитаемое название объекта;verbose_name_plural
- человекочитаемое название во множественном числе.
Кроме того, переопределим дандер-метод __str__
в каждом классе, чтобы объекты имели более понятное текстовое представление.
from django.db import models
class Airline(models.Model):
class Meta:
db_table = "airline"
verbose_name = "авиакомпания"
verbose_name_plural = "авиакомпании"
name = models.CharField(max_length=50, verbose_name="Название")
def __str__(self):
return self.name
В этой модели определим только одно текстовое поле - "Название".
from django.db import models
from django.utils import timezone
class Flight(models.Model):
class Meta:
db_table = "flight"
verbose_name = "рейс"
verbose_name_plural = "рейсы"
class Type(models.TextChoices):
DEPARTURE = "departure", "Отлёт"
ARRIVAL = "arrival", "Прилёт"
airline = models.ForeignKey(Airline, on_delete=models.CASCADE, related_name="flights", verbose_name="Авиакомпания")
type = models.CharField(max_length=9, choices=Type.choices, verbose_name="Тип")
gate = models.CharField(max_length=5, verbose_name="Гейт")
date = models.DateTimeField(verbose_name="Время отправления")
def __str__(self):
return (
f"{self.airline} ({self.get_type_display()}), "
f"{self.gate} - {timezone.localtime(self.date).strftime('%d.%m.%y %H:%M')}"
)
В этой модели определим внешний ключ к таблице авиакомпаний и напишем related_name
- flights
. По этому имени мы
сможем обращаться к объектам рейсов из модели авиакомпаний.
Создадим подкласс Type
, наследуемый от models.TextChoices
, аналог Enum в Django. В нём опишем два значения:
прилёт и отлёт, их значения, которые будет храниться в БД, и их человекочитаемые значения.
Далее создадим в модели текстовое поле "Тип" и с помощью атрибута choices
обеспечим связь с подклассом Type
.
Это обеспечит валидацию данных для этого поля и возможность выбора в админ-панели.
Помимо этого добавим текстовое поле "Гейт" и поле с датой и временем "Время отправления".
В методе __str__
из особенностей: self.get_type_display()
, с помощью которого мы можем получить человекочитаемое
название типа рейса, и timezone.localtime(self.date)
, с помощью которого мы получим дату и время в часовом поясе,
обозначенном в settings.py
(по умолчанию в БД дата и время хранятся в UTC).
from django.contrib.auth.models import User
from django.db import models
class Booking(models.Model):
class Meta:
db_table = "booking"
verbose_name = "бронь"
verbose_name_plural = "брони"
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="bookings", verbose_name="Пассажир")
flight = models.ForeignKey(Flight, on_delete=models.CASCADE, related_name="bookings", verbose_name="Рейс")
registered = models.BooleanField(default=False, verbose_name="Зарегистрирован?")
ticket = models.PositiveSmallIntegerField(blank=True, null=True, verbose_name="Номер билета")
def __str__(self):
user_full_name = f"{self.user.last_name} {self.user.first_name}"
return f"{user_full_name if user_full_name != ' ' else self.user.username} - {self.flight}"
В этой модели добавим два внешних ключа: на User
(встроенная auth модель, которую мы будем использовать,
чтобы хранить пользователей) и Flight
(рейс). Для обоих полей напишем related_name="bookings"
А также булевое поле "Зарегистрирован?" (по умолчанию ставится как False), необходимое для подтверждения брони администраторами, и PositiveSmallInteger поле "Номер билета", которое может быть числом в пределах от 0 до 32767 и которое так же вводится администратором.
from django.contrib.auth.models import User
from django.core import validators
from django.db import models
class Feedback(models.Model):
class Meta:
db_table = "feedback"
verbose_name = "отзыв"
verbose_name_plural = "отзывы"
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="feedbacks", verbose_name="Пассажир")
flight = models.ForeignKey(Flight, on_delete=models.CASCADE, related_name="feedbacks", verbose_name="Рейс")
text = models.TextField(verbose_name="Текст")
rating = models.PositiveSmallIntegerField(
validators=[validators.MinValueValidator(1), validators.MaxValueValidator(10)], verbose_name="Рейтинг"
)
date = models.DateTimeField(auto_now_add=True, verbose_name="Создан")
def __str__(self):
return f"{self.user.last_name} {self.user.first_name} - {self.flight}"
В этом модели так же создаём два внешних ключа: на User
и на Flight
(в качестве related_name
выберем feedbacks
),
а также текстовое поле для текста отзывов, PositiveSmallInteger поле "Рейтинг" с валидаторами,
чтобы значение было от 1 до 10, и поле даты и времени, которое заполняется автоматически при создании записи.
После создания всех моделей нужно обязательно сделать миграции:
А так же создать суперпользователя: