Celmar Y.
Celmar Y.

Reputation: 321

Derive a Django 3.0 Choices class from existing Enum?

Django 3 brought a new way to define field choides: Field.choices. This brings some adavantages, e.g. enforces uniqueness and allows supplying human readable tags.

Unfortunately, I can't find a clean way to define the choices in a non-django module, so that these choices can be imported from non-django applications. Concretely:

Therefore I want to define these colors as stand-alone class in exactly one place, e.g.:

class ShapeColor(Enum):
    BLUE = 1
    GREEN = 2
    RED = 3

In the past I imported this Enum 'ShapeColor' anywhere I needed it. But I have not found a clean way to translate this Enum into the new models.IntegerChoices class. I tried to inherit from my Enum:

class ColorChoices(models.IntegerChoices, ShapeColors):
    pass

But of course this gives a TypeError("Cannot extend enumerations").

It would be great if anyone had a suggestion on how to cleanly derive a django choice enum from an existing Enum or similar construct.

Upvotes: 2

Views: 837

Answers (1)

Ethan Furman
Ethan Furman

Reputation: 69110

Digging into the Django code a bit, it turns out that Choices, IntegerChoices, and TextChoices are all Django's versions of the basic Enum data type. So, assuming feasibility, the easiest thing to do would be to create ShapeColor as a models.IntegerChoices directly. If that's not feasible (maybe Django is not available where your other tools are running), then the next best thing would be to create ColorChoices from ShapeColor:

ColorChoices = model.IntegerChoices(
        'ColorChoices',
        [(m.name, m.value) for m in ShapeColor],
        )

Upvotes: 2

Related Questions