Модели в Django и их поля
Поля — это столбцы
Каждое поле модели — экземпляр класса из 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
Чем отличаются параметры null=True и blank=True?
Какое поле лучше подходит для хранения цены товара в рублях с копейками?
Добавьте в модель Post поле status — строку до 10 символов с выбором из вариантов
Status.choices и значением по умолчанию Status.DRAFT.
class Post(models.Model):
class Status(models.TextChoices):
DRAFT = "DF", "Черновик"
PUBLISHED = "PB", "Опубликован"
title = models.CharField(max_length=250)
status = models.CharField(max_length=10, choices=Status.choices, default=Status.DRAFT)
Какие поля автоматически заполняют дату?
Добавьте в модель Article поле slug — уникальный слаг длиной до 200 символов,
и класс Meta с сортировкой по убыванию поля created.
class Article(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created"]
Какой метод модели принято определять, чтобы он возвращал канонический адрес объекта на сайте?
Войдите, чтобы отмечать пройденные уроки.