Как повторно использовать существующий python Enum в Django для выбора?
Django имеет свои собственные типы перечисления, такие как model.TextChoices.
Однако, если вы уже используете традиционные объекты python Enum в своей кодовой базе, было бы неплохо повторно использовать их для определения полей без переопределения всех значений.
Есть ли элегантный прямой способ сделать это без излишнего количества шаблонов?
Что я пробовал:
- создание класса
models.TextChoicesизEnumкажется невозможным без ручного объявления значений - создание
choicesпараметра изEnumвместо того, чтобы иметь дело сmodels.TextChoices, но тогда такие вещи, какobj.field == ENUM.XXXне будут работать, потому что Enums не делают сравнения значений, какmodels.TextChoices, среди прочего.
Есть ли элегантный способ сделать это?
form enum import Enum
class YEAR_IN_SCHOOL(Enum):
FRESHMAN = 'FR'
SOPHOMORE = 'SO'
JUNIOR = 'JR'
SENIOR = 'SR'
GRADUATE = 'GR'
class MyModel(models.Model):
year_in_school = django_model_field_choices_using_enum(YEAR_IN_SCHOOL)
Так что:
- Сравнение с работой ENUM
my_model.year_in_school == YEAR_IN_SCHOOL.FRESHMAN
- Сохранение с помощью Enum работает
my_model.year_in_school = YEAR_IN_SCHOOL.FRESHMAN
my_model.save()
Вы можете определить его как обычный django models.CharField с choices из вашего Enum
I.e.:
class MyModel(models.Model):
year_in_school = models.CharField(max_length=2,
choices=[(x.value, x.name) for x in YEAR_IN_SCHOOL]
)
Однако использование в этом случае будет немного другим (необходимо указать .value при сравнении/сохранении:
my_model.year_in_school == YEAR_IN_SCHOOL.FRESHMAN.value
Если вы хотите иметь его без .value - то удалите Enum - т.е. сделайте простой класс.
Тогда поиск вариантов будет с inspect:
import inspect
class YEAR_IN_SCHOOL:
FRESHMAN = 'FR'
SOPHOMORE = 'SO'
JUNIOR = 'JR'
SENIOR = 'SR'
GRADUATE = 'GR'
choices = [(y, x) for x, y in inspect.getmembers(YEAR_IN_SCHOOL)]
И задание/сравнение будет таким же, как в вашем вопросе