Что такое IntegerChoices в Django и для чего он используется

Ответ

Класс models.IntegerChoices в Django — это современный способ создания перечислений (enum) для полей моделей, который пришел на смену классическому подходу с кортежами. Он делает код более читаемым, безопасным и самодокументируемым.

Основная задача — связать целочисленные значения, хранящиеся в базе данных, с понятными именованными константами в коде.

Преимущества:

  • Читаемость: Вместо "магических чисел" (например, status=1) используется понятный код: status=Article.Status.PUBLISHED.
  • Автоматизация: Автоматически генерирует атрибут .choices для передачи в поле модели.
  • Удобный API: Предоставляет свойства .label (человекочитаемое имя) и .value (значение для БД).

Пример использования:

from django.db import models

class Article(models.Model):
    class Status(models.IntegerChoices):
        DRAFT = 0, 'Черновик'
        PUBLISHED = 1, 'Опубликовано'
        ARCHIVED = 2, 'В архиве'

    title = models.CharField(max_length=200)
    status = models.IntegerField(
        choices=Status.choices, 
        default=Status.DRAFT
    )

# Использование в коде:
article = Article.objects.get(pk=1)

# Проверка статуса
if article.status == Article.Status.PUBLISHED:
    print("Статья опубликована.")

# Получение человекочитаемого названия
print(article.get_status_display()) # Выведет: 'Опубликовано'

# Использование API самого enum
print(Article.Status.PUBLISHED.label) # Выведет: 'Опубликовано'
print(Article.Status.PUBLISHED.value) # Выведет: 1

Ответ 18+ 🔞

Смотри, ну это ж просто пиздец какой-то праздник для задрота, а не фича! Раньше-то, блядь, как было? Сидишь, выдумываешь эти хуёвые кортежи, мозги ебёшь:

STATUS_CHOICES = (
    (0, 'Черновик'),
    (1, 'Опубликовано'),
    (2, 'В архиве'),
)

А потом в коде, сука, опечатаешься где-нибудь, вместо единицы двойку впихнёшь — и всё, пиздец, ищи эту ошибку, волосы на жопе рви! Магические числа, блядь, они же как минное поле — наступил и тебе пизда.

А тут приходят эти умные дядьки из Django и говорят: «На, ебушки-воробушки, лови IntegerChoices!». И ведь реально удобно, ёпта!

Смысл-то простой, как три копейки: связать цифру в базе (которую там удобно хранить и индексировать) с нормальным, человеческим названием прямо в коде. Чтобы не article.status == 1, а article.status == Article.Status.PUBLISHED. Читаешь и сразу понимаешь, о чём речь, а не гадаешь, что за хуйня такая «единица».

И оно само, блядь, всё делает! Напишешь класс — а у него уже готовый атрибут .choices торчит, который прямо в поле модели и засунешь. Красота!

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

from django.db import models

class Article(models.Model):
    class Status(models.IntegerChoices):
        DRAFT = 0, 'Черновик'
        PUBLISHED = 1, 'Опубликовано'
        ARCHIVED = 2, 'В архиве'

    title = models.CharField(max_length=200)
    status = models.IntegerField(
        choices=Status.choices, 
        default=Status.DRAFT
    )

Видишь? Внутри модели завел себе класс Status, наследуешься от IntegerChoices и просто перечисляешь варианты. Слева — константа, справа — пара: значение для базы и человеческая надпись.

А пользоваться — одно ебаное удовольствие:

# Берём статью
article = Article.objects.get(pk=1)

# Проверяем статус — чисто, понятно, без подвоха
if article.status == Article.Status.PUBLISHED:
    print("Статья опубликована.")

# Хочешь красивое название для юзера — пожалуйста, встроенный метод
print(article.get_status_display()) # Выведет: 'Опубликовано'

# А можно и прямо у самого enum'а спросить
print(Article.Status.PUBLISHED.label) # 'Опубликовано'
print(Article.Status.PUBLISHED.value) # 1

В общем, вещь охуенная. Код становится чище, ошибок меньше, а жизнь — чуть светлее. Бери и пользуйся, не изобретай велосипед, блядь.