← Назад к вопросам
Какой тип данных хранится в IntegerChoices?
1.0 Junior🔥 111 комментариев
#Django#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# IntegerChoices: типы данных и использование
IntegerChoices — это класс из Django, который позволяет определять набор именованных целых чисел с удобным интерфейсом выбора. Это комбинирует типизацию с удобством использования.
Основной тип данных
В IntegerChoices хранится целое число (int), а не строка:
from django.db.models import IntegerChoices
class OrderStatus(IntegerChoices):
PENDING = 1, "Ожидание"
PROCESSING = 2, "Обработка"
COMPLETED = 3, "Завершено"
CANCELLED = 4, "Отменено"
# Проверка типов
print(type(OrderStatus.PENDING)) # <enum 'OrderStatus'>
print(OrderStatus.PENDING.value) # 1 (целое число)
print(OrderStatus.PENDING.label) # "Ожидание" (строка)
print(type(OrderStatus.PENDING.value)) # <class 'int'>
Использование в моделях
from django.db import models
class Order(models.Model):
class Status(IntegerChoices):
PENDING = 1, "Ожидание"
PROCESSING = 2, "Обработка"
COMPLETED = 3, "Завершено"
CANCELLED = 4, "Отменено"
status = models.IntegerField(
choices=Status.choices,
default=Status.PENDING
)
# В БД сохраняется целое число: 1, 2, 3 или 4
# Создание записи
order = Order.objects.create(status=Order.Status.PROCESSING)
print(order.status) # 2
print(order.get_status_display()) # "Обработка" (из label)
TextChoices vs IntegerChoices
# TextChoices — хранит строки
class Color(TextChoices):
RED = "red", "Красный"
BLUE = "blue", "Синий"
GREEN = "green", "Зелёный"
field = models.CharField(choices=Color.choices)
# В БД: 'red', 'blue' или 'green'
# IntegerChoices — хранит целые числа
class Priority(IntegerChoices):
LOW = 1, "Низкий"
MEDIUM = 2, "Средний"
HIGH = 3, "Высокий"
field = models.IntegerField(choices=Priority.choices)
# В БД: 1, 2 или 3
Типизация в коде
from typing import Literal
from django.db.models import IntegerChoices
class PaymentStatus(IntegerChoices):
PENDING = 1, "В ожидании"
APPROVED = 2, "Одобрено"
REJECTED = 3, "Отклонено"
def process_payment(status: Literal[1, 2, 3]) -> str:
if status == PaymentStatus.APPROVED:
return "Payment accepted"
return "Payment declined"
# Или с использованием самого enum
def process_payment(status: PaymentStatus) -> str:
if status == PaymentStatus.APPROVED:
return "Payment accepted"
return "Payment declined"
Практические примеры
Сравнение и фильтрация
class TaskStatus(IntegerChoices):
NEW = 1, "Новая"
IN_PROGRESS = 2, "В процессе"
DONE = 3, "Завершена"
ARCHIVED = 4, "В архиве"
class Task(models.Model):
status = models.IntegerField(choices=TaskStatus.choices)
# Фильтрация
active_tasks = Task.objects.filter(
status__in=[TaskStatus.NEW, TaskStatus.IN_PROGRESS]
)
# Прямое сравнение
if task.status == TaskStatus.DONE:
task.archived_at = now()
# Получить все значения
all_statuses = list(TaskStatus)
print(all_statuses) # [1, 2, 3, 4]
# Получить все метки (labels)
status_labels = [label for _, label in TaskStatus.choices]
print(status_labels) # ["Новая", "В процессе", "Завершена", "В архиве"]
Сериализация для API
from rest_framework import serializers
class TaskSerializer(serializers.ModelSerializer):
status = serializers.ChoiceField(choices=TaskStatus.choices)
status_display = serializers.CharField(source='get_status_display', read_only=True)
class Meta:
model = Task
fields = ['id', 'title', 'status', 'status_display']
# Response пользователю
{
"id": 1,
"title": "Implement feature",
"status": 2, # целое число в БД
"status_display": "В процессе" # для показа
}
Сериализация в Pydantic
from pydantic import BaseModel
from django.db.models import IntegerChoices
class UserRole(IntegerChoices):
ADMIN = 1, "Администратор"
MODERATOR = 2, "Модератор"
USER = 3, "Пользователь"
class UserResponse(BaseModel):
id: int
username: str
role: int # IntegerChoices.value это int
role_label: str # Метка для отображения
class Config:
# Если используем Django модель
from_attributes = True
Преимущества IntegerChoices
# Сравнение с хардкодом
# ❌ Плохо: магические числа
def is_approved(status):
return status == 2 # Что такое 2?
# ✅ Хорошо: семантические имена
class DocStatus(IntegerChoices):
PENDING = 1, "На согласование"
APPROVED = 2, "Одобрено"
REJECTED = 3, "Отклонено"
def is_approved(status):
return status == DocStatus.APPROVED
Итерация и работа с выборами
class Permission(IntegerChoices):
READ = 1, "Чтение"
WRITE = 2, "Запись"
DELETE = 4, "Удаление"
ADMIN = 8, "Администрирование"
# Итерация
for permission in Permission:
print(f"{permission.name} = {permission.value} ({permission.label})")
# Output:
# READ = 1 (Чтение)
# WRITE = 2 (Запись)
# DELETE = 4 (Удаление)
# ADMIN = 8 (Администрирование)
# Доступ по имени
print(Permission['READ']) # Permission.READ
print(Permission['READ'].value) # 1
# Доступ по значению
print(Permission(2)) # Permission.WRITE
print(Permission(2).label) # "Запись"
Суммирование: IntegerChoices.choices
class Status(IntegerChoices):
DRAFT = 1, "Черновик"
PUBLISHED = 2, "Опубликовано"
ARCHIVED = 3, "В архиве"
print(Status.choices)
# Вывод: [(1, 'Черновик'), (2, 'Опубликовано'), (3, 'В архиве')]
# Для использования в моделях
class Article(models.Model):
status = models.IntegerField(choices=Status.choices, default=Status.DRAFT)
Вывод
IntegerChoices хранит целые числа (int), а не строки. Каждый вариант имеет:
- value — целое число для хранения в БД
- label — человекочитаемую строку для отображения
- name — программное имя константы
Это намного удобнее, чем магические числа, и обеспечивает типобезопасность.