Solución:
Django 3.0 tiene soporte incorporado para Enums
Ejemplo:
from django.utils.translation import gettext_lazy as _
class Student(models.Model):
class YearInSchool(models.TextChoices):
FRESHMAN = 'FR', _('Freshman')
SOPHOMORE = 'SO', _('Sophomore')
JUNIOR = 'JR', _('Junior')
SENIOR = 'SR', _('Senior')
GRADUATE = 'GR', _('Graduate')
year_in_school = models.CharField(
max_length=2,
choices=YearInSchool.choices,
default=YearInSchool.FRESHMAN,
)
Estos funcionan de manera similar a la enumeración de la biblioteca estándar de Python, pero con algunas modificaciones:
- Los valores de los miembros de enumeración son una tupla de argumentos que se utilizan al construir el tipo de datos concreto. Django admite agregar un valor de cadena adicional al final de esta tupla para usarlo como el nombre legible por humanos, o
label
. loslabel
puede ser una cadena traducible perezosa. Por lo tanto, en la mayoría de los casos, el valor del miembro será un(value, label)
dos tuplas. Si no se proporciona una tupla, o el último elemento no es una cadena (perezosa), la etiqueta se genera automáticamente a partir del nombre del miembro. - A
.label
La propiedad se agrega a los valores, para devolver el nombre legible por humanos. Se agregan varias propiedades personalizadas a las clases de enumeración:.choices
,.labels
,.values
, y.names
– para facilitar el acceso a las listas de esas partes separadas de la enumeración. Usar.choices
como un valor adecuado para pasar a opciones en una definición de campo. - El uso de
enum.unique()
se aplica para garantizar que los valores no se puedan definir varias veces. Es poco probable que esto se espere en las elecciones de un campo.
Para más información, consulte la documentación.
Para Django 2.xy versiones anteriores:
Tu defines un Enum
configurando las diversas opciones como se documenta aquí:
class TransactionStatus(Enum):
INITIATED = "INITIATED"
PENDING = "PENDING"
COMPLETED = "COMPLETED"
FAILED = "FAILED"
ERROR = "ERROR"
¡Tenga en cuenta que no hay comas! Esto le permite más adelante en su código hacer referencia a TransactionStatus.ERROR
o TransactionStatus.PENDING
.
El resto de su código es correcto. Obtienes el choices
creando tuplas de option.name
, option.value
.
ACTUALIZACIÓN: para Django 3.xy versiones posteriores, use los tipos incorporados TextChoices
, IntegerChoices
y Choices
como se describe aquí. De esa forma no tiene que construir el choices
tuple usted mismo.
El problema en tu código es que INITIATED = "INITIATED",
una coma después INITIATED
opción y otras opciones. cuando agregamos una coma después de cualquier cadena, se convertirá en una tupla. Vea un ejemplo a continuación
s="my str"
print(type(s))
# output: str
s="my str",
print(type(s))
# output: tuple
modelos.py
class Transaction(models.Model):
trasaction_status = models.CharField(max_length=255, choices=TransactionStatus.choices())
transaction_type = models.CharField(max_length=255, choices=TransactionType.choices())
enums.py
class TransactionType(Enum):
IN = "IN"
OUT = "OUT"
@classmethod
def choices(cls):
print(tuple((i.name, i.value) for i in cls))
return tuple((i.name, i.value) for i in cls)
class TransactionStatus(Enum):
INITIATED = "INITIATED"
PENDING = "PENDING"
COMPLETED = "COMPLETED"
FAILED = "FAILED"
ERROR = "ERROR"
@classmethod
def choices(cls):
print(tuple((i.name, i.value) for i in cls))
return tuple((i.name, i.value) for i in cls)