Перейти к содержанию

Модели

Нам необходимо описать БД средствами 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, и поле даты и времени, которое заполняется автоматически при создании записи.

После создания всех моделей нужно обязательно сделать миграции:

python manage.py makemigrations
python manage.py migrate

А так же создать суперпользователя:

python manage.py createsuperuser