Класс Meta

Внутренний класс Meta определяется внутри модели Django и содержит параметры, управляющие поведением модели на уровне базы данных и ORM. Он позволяет задавать имя таблицы, сортировку по умолчанию, уникальные ограничения, отображение в административной панели и многие другие настройки. Класс Meta не влияет на структуру полей модели, но определяет метаданные, которые используются Django при работе с моделью.

Синтаксис

pythonfrom django.db import models

class MyModel(models.Model):
  # поля модели
  name = models.CharField(max_length=100)

  class Meta:
    # параметры метаданных
    db_table = "my_table"
    ordering = ["name"]
    verbose_name = "My Model"

Пример

Определим модель Article с классом Meta, который задает имя таблицы и сортировку по умолчанию по убыванию даты создания:

pythonfrom django.db import models

class Article(models.Model):
  title = models.CharField(max_length=200)
  content = models.TextField()
  created_at = models.DateTimeField(auto_now_add=True)
  status = models.CharField(max_length=20)

  class Meta:
    db_table = "blog_articles"
    ordering = ["-created_at"]
    verbose_name = "Статья"
    verbose_name_plural = "Статьи"

После этого запросы к модели будут возвращать записи, отсортированные по убыванию даты создания, а в административной панели модель будет отображаться с указанными названиями:

pythonfrom myapp.models import Article

# запрос автоматически использует сортировку из Meta
articles = Article.objects.all()
for article in articles:
  print(article.title)

Результат выполнения кода:

python"Latest Article"
"Middle Article"
"Oldest Article"

Пример

Используем класс Meta для задания уникального ограничения на пару полей и настройки абстрактной модели:

pythonfrom django.db import models

class Category(models.Model):
  name = models.CharField(max_length=100)
  slug = models.SlugField()

  class Meta:
    unique_together = ["name", "slug"]
    abstract = True

class Product(models.Model):
  category = models.ForeignKey(Category, on_delete=models.CASCADE)
  name = models.CharField(max_length=200)
  price = models.DecimalField(max_digits=10, decimal_places=2)

  class Meta:
    # уникальное ограничение на пару полей
    unique_together = ["category", "name"]
    # сортировка по умолчанию
    ordering = ["category", "name"]
    # имя таблицы в базе данных
    db_table = "shop_products"
    # индексы для оптимизации запросов
    indexes = [
      models.Index(fields=["category", "price"]),
    ]

При создании миграций Django автоматически создаст уникальное ограничение на комбинацию полей category и name в таблице shop_products, а также индекс для ускорения запросов по этим полям:

pythonfrom myapp.models import Product, Category

# создаем категорию
category = Category.objects.create(name="Electronics", slug="electronics")

# создаем продукты
Product.objects.create(category=category, name="Laptop", price=999.99)
Product.objects.create(category=category, name="Phone", price=599.99)

# попытка создать дубликат вызовет ошибку IntegrityError
try:
  Product.objects.create(category=category, name="Laptop", price=799.99)
except Exception as e:
  print(e)

Результат выполнения кода:

python"UNIQUE constraint failed: shop_products.category_id, shop_products.name"

Смотрите также

  • атрибут db_table,
    который задает имя таблицы в базе данных для модели
  • атрибут ordering,
    который определяет сортировку записей по умолчанию
  • атрибут verbose_name,
    который задает отображаемое имя модели в единственном числе
  • атрибут verbose_name_plural,
    который задает отображаемое имя модели во множественном числе