Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

294
Views
Igualdad de atributos de enumeración de Django

Estoy usando enumeraciones en un modelo Django, como:

 class AwesomeNess(Enum): slight = "SLIGHT" very = "VERY" class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) awesomeness = models.CharField( max_length=255, choices=[(tag.value, tag.name) for tag in AwesomeNess], default=AwesomeNess.slight )

Esto funciona bien cuando uso la función de filtro de Django, como:

 d = Choice.objects.filter(awesomeness=AwesomeNess.slight)

Sin embargo, no funciona si lo hago:

 choice_obj = Choice.objects.get(id=1) choice_obj.awesomeness == AwesomeNess.slight # will return False choice_obj.awesomeness == "AwesomeNess.slight" # will return True

Dado que los valores se almacenan como cadenas, parece que Django se olvida de devolverlos a una enumeración al devolver los datos. Esto genera inconsistencias al codificar, ya que los filtros del modelo Django pueden consultar la enumeración, mientras que el filtrado de igualdad de atributos requiere que use la representación de cadena de la enumeración.

EDITAR: las enumeraciones se importan de otra clase de modelo, por lo que reemplazarla con la clase de opciones integrada de Django no es una opción.

EDIT2: Mientras investigo esto, también noto lo siguiente:

 myobj = Choice.objects.get(id=1) myobj.awesomeness # <<-- string type myobj.awesomeness = AwesomeNess.very <<-- object changes type to enum myobj.save() myobj2 = Choice.objects.get(id=1) <<-- upon reload from db, the updated value is returned as string

Como usuario novato de Django, esto me parece increíblemente peligroso y no se menciona en ninguno de los artículos de "cómo usar enumeraciones con django" que he leído. ¿Esto se debe simplemente al hecho de que estoy en una versión demasiado antigua de Django?

¿Hay alguna forma de evitar esto? ¿Estoy haciendo algo muy mal? ¡Se agradecen los punteros! oh, bwt: esto es en Django 2.2.24. ¿Quizás las versiones posteriores han mejorado el soporte de enumeración?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

La razón por la que esto sucede es porque las opciones llaman a str en el valor que se proporciona, y esto significa que almacenará "AwesomeNess.slight" como una cadena (si está configurada como predeterminada).

Desde django-3.0 , puede trabajar con una clase TextChoices [Django-doc] que es lo mismo que usar Enum . Por lo tanto, puede definir un modelo TextChoices con:

 class Choice(models.Model): class AwesomNess (models.TextChoices): SLIGHT = 'SLIGHT', 'slight' VERY = 'VERY', 'very' question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) awesomeness = models.CharField( max_length=255, choices=AwesomeNess .choices , default=AwesomeNess.SLIGHT )

para versiones anteriores, debe especificar que trabaja con el valor de AwesomeNess :

 class AwesomeNess(Enum): slight = 'SLIGHT' very = 'VERY' class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) awesomeness = models.CharField( max_length=255, choices=[(tag.value, tag.name) for tag in AwesomeNess], default= AwesomeNess.slight.value )
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!