Модели в Django и их поля

⏱ 25 мин · 🧩 заданий: 6

Поля — это столбцы

Каждое поле модели — экземпляр класса из django.db.models. Тип поля определяет:

  • тип столбца в базе данных (VARCHAR, INTEGER, DATE…);
  • HTML-виджет в формах и админке;
  • правила валидации.

Основные типы полей

Текст

Поле Для чего
CharField(max_length=200) Короткая строка, max_length обязателен
TextField() Длинный текст без ограничения
SlugField() Слаг для URL: moy-pervyj-post
EmailField() Email с проверкой формата
URLField() Адрес сайта

Числа

Поле Для чего
IntegerField() Целое число
PositiveIntegerField() Целое ≥ 0
FloatField() Число с плавающей точкой
DecimalField(max_digits=10, decimal_places=2) Точная десятичная дробь (деньги!)

Дата и время

published = models.DateField()
created = models.DateTimeField(auto_now_add=True)   # при создании
updated = models.DateTimeField(auto_now=True)       # при каждом save()
publish = models.DateTimeField(default=timezone.now) # по умолчанию «сейчас», но можно изменить

auto_now_add и auto_now делают поле нередактируемым в формах. Если дату нужно задавать вручную — используйте default=timezone.now (функция передаётся без скобок, чтобы вызываться в момент создания).

Прочие

Поле Для чего
BooleanField(default=False) Да/нет
FileField(upload_to="docs/") Файл
ImageField(upload_to="photos/") Картинка (нужен пакет Pillow)
JSONField() Произвольные данные JSON
UUIDField() UUID

Связи между таблицами (ForeignKey, ManyToManyField, OneToOneField) — тема отдельного урока.

Общие параметры полей

class Product(models.Model):
    name = models.CharField("Название", max_length=200, unique=True)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    discount = models.PositiveIntegerField(null=True, blank=True, help_text="В процентах")
    sku = models.CharField(max_length=30, db_index=True)
    is_active = models.BooleanField(default=True, verbose_name="Активен")
Параметр Что делает
verbose_name (или первый аргумент) Название для людей
null=True Разрешить NULL в базе
blank=True Разрешить пустое значение в формах
default Значение по умолчанию
unique=True Значения не повторяются
db_index=True Создать индекс для быстрого поиска
choices Ограничить набором вариантов
help_text Подсказка в форме
editable=False Не показывать в формах

null или blank?

null — про базу данных, blank — про валидацию. Для строк обычно blank=True без null (пустая строка вместо NULL). Для чисел и дат, которые могут отсутствовать, — оба: null=True, blank=True.

Варианты выбора: choices

Современный способ — перечисления TextChoices / IntegerChoices:

class Post(models.Model):
    class Status(models.TextChoices):
        DRAFT = "DF", "Черновик"
        PUBLISHED = "PB", "Опубликован"

    status = models.CharField(max_length=2, choices=Status.choices, default=Status.DRAFT)

В базе хранится "DF", а людям показывается «Черновик». Получить подпись: post.get_status_display(). Сравнивать: post.status == Post.Status.PUBLISHED.

Класс Meta

class Post(models.Model):
    ...

    class Meta:
        ordering = ["-publish"]                # сортировка по умолчанию
        verbose_name = "пост"
        verbose_name_plural = "посты"
        indexes = [models.Index(fields=["-publish"])]
        constraints = [
            models.UniqueConstraint(fields=["slug", "publish"], name="unique_slug_publish"),
        ]
        db_table = "posts"                     # своё имя таблицы (редко нужно)

Минус перед именем поля означает сортировку по убыванию.

Методы модели

Модель — обычный класс, ей можно добавлять методы и свойства:

from django.urls import reverse


class Product(models.Model):
    ...

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse("shop:product_detail", args=[self.slug])

    @property
    def final_price(self):
        if self.discount:
            return self.price * (100 - self.discount) / 100
        return self.price

В шаблоне: {{ product.final_price }}. Это и есть «толстые модели»: логика рядом с данными.

Итог

  • Тип поля определяет столбец в БД, виджет и валидацию.
  • CharField требует max_length, деньги храним в DecimalField.
  • null — для базы, blank — для форм.
  • TextChoices + choices ограничивают значения, Meta настраивает модель.
  • Методы __str__ и get_absolute_url стоит писать всегда.

Практика решено 0 из 6

Вы не вошли — ответы проверяются, но прогресс не сохранится. Войти или зарегистрироваться.
Задание 1 Один вариант ответа

Чем отличаются параметры null=True и blank=True?

Задание 2 Один вариант ответа

Какое поле лучше подходит для хранения цены товара в рублях с копейками?

Задание 3 Написать код

Добавьте в модель Post поле status — строку до 10 символов с выбором из вариантов Status.choices и значением по умолчанию Status.DRAFT.

Задание 4 Несколько вариантов

Какие поля автоматически заполняют дату?

Задание 5 Написать код

Добавьте в модель Article поле slug — уникальный слаг длиной до 200 символов, и класс Meta с сортировкой по убыванию поля created.

Задание 6 Ввод ответа

Какой метод модели принято определять, чтобы он возвращал канонический адрес объекта на сайте?

Войдите, чтобы отмечать пройденные уроки.