Package: django-echoices
Django-EChoicesChoices for Django model fields as enumerationFeaturesSpecializedenum typesSpecializedmodel fieldsAccessible intemplatesRequirementsPython>= 3.5Django>= 1.11.29InstallationUsingPyPIRunpip installdjango-echoices.Using the source codeMake sure`pandoc<http://pandoc.org/index.html>`__ is installedRun./pypi_packager.shRunpip installdist/django_echoices-x.y.z-[...].wheel, wherex.y.zmust be replaced by the actual version number and[...]depends on your packaging configurationUsageEnumerationFirst, define your choices enumeration (in yourmodels.pyfor
example):from echoices.enums import EChoice

class EStates(EChoice):
    # format is: (value -> char or str or int, label -> str)
    CREATED = ('c', 'Created')
    SUBMITTED = ('s', 'Submitted')Model fieldRegular model fieldThen, either use a regular model field:from django.db import models

class MyModel(models.Model):
    state = models.CharField(max_length=EStates.max_value_length(),
                             choices=EStates.choices(),
                             default=EStates.CREATED.value)Note: If your value is anint, you can usemodels.IntegerFieldinstead.Specialized fieldYou can also use specialized field. Using such a field, you will then
only handleEchoiceinstances.from django.db import models
from echoices.fields import make_echoicefield

class MyModel(models.Model):
    # `max_length` is set automatically
    state = make_echoicefield(EStates, default=EStates.CREATED)Note:MyModel.statewill beEstatesinstance stored in aEStatesFieldfield. Seedocumentationfor more
details.WARNING: requires special handling of migrations. Read more in thedocumentation.DerivationYou can add your own fields to thevalueandlabelones. To do
so, you have to override theinit() and your signature must look
like:self, value, label, *argswhere you replace*argswith
your own positional arguments, as you would do when defining a custom
Enum. Donotcall the super().init(), asvalueandlabelare already set internally byEChoice.As when dealing with a derived Enum, you can also add your own methods.from echoices.enums import EChoice

class EMyChoices(EChoice):
    """Another variant of EChoice with additionnal content"""

    MY_CHOICE = (1, 'First choice', 'my additional value')

    def __init__(self, value, label, my_arg):
        self.my_arg = my_arg
        # Note: super().__init__() shall *not* be called!

    def show_myarg(self):
        """Used as: EMyChoices.MY_CHOICE.show_myarg()"""
        print(self.my_arg)

    @classmethod
    def show_all(cls):
        """Used as: EMyChoices.show_all()"""
        print(", ".join([e.my_arg for e in list(cls)]))In templatesAssume aContext(dict(estates=myapp.models.EStates))is provided to
the following templates.Fields of theEChoicecan be accessed in the templates as:{{ estates.CREATED.value }}
{{ estates.CREATED.label }}EChoicecan also be enumerated:{% for state in estates %}
    {{ state.value }}
    {{ state.label }}
{% endfor %}Short documentationSpecialized enum typesenums.EChoiceBase enum type. Each enum element is a tuple(value, label), where
[t]he first element in each tuple is the actual value to be set on the
model, and the second element is the human-readable namedoc.
Valuesmustbe unique. Can be derived for further customization.enums.EOrderedChoiceSupports ordering of elements.EOrderedChoice.choices()takes an
extra optional argument,order, which supports three values:
‘sorted’, ‘reverse’ or ‘natural’ (default). Ifsorted, the choices
are ordered according to their value. Ifreverse, the choices are
ordered according to their value as if each comparison were reversed. Ifnatural, the order is the one used when instantiating the
enumeration.enums.EAutoChoiceGenerates auto-incremented numeric values. It’s then used like:from echoices.enums import EAutoChoice

class EStates(EAutoChoice):
    # format is: label -> str
    CREATED = 'Created'
    SUBMITTED = 'Submitted'APIOverriden EnumMeta methodsEChoice.__getitem__(), such that you can retrieve anEChoiceinstance usingEChoice['my_value']Additional classmethodschoices()generates the choices as expected by a Django model
fieldmax_value_length()returns the max length for the Django model
field, if the values are stringsvalues()returns a list of all the valuesget(value, default=None)returns the EChoice instance having that
value, else returns the defaultSpecialized model fieldsfields.EChoiceFieldviafields.make_echoicefield()Deal directly with the enum instances instead of their DB storage value.
The specialized field will be derived from amodels.Fieldsubclass,
the internal representation is deduced from the value type. So for
example if the values are strings, then the theEChoiceFieldwill
subclassmodels.CharField; and if the values are integers then it
will bemodels.IntegerField. Actually supportsstr,int,floatand (non-null)boolas enum values.make_echoicefield()will return an instance ofEChoiceFieldwhich subclasses a field type frommodels.CharField. The exact name
of the field type will beMyEnumNameFieldin Django >= 1.9, note the
suffixed ‘Field’. For earlier versions of Django, it will beEChoiceField.Thus,MyModel.my_echoice_fieldwill be anEChoiceinstance
stored in anEChoiceFieldfield.MigrationsSince the field is generated with the help of a factory function, it
does not exist as is as a field class inechoices.fields. But, when
generating a migration file, Django will set the class of the field as
the resulting class frommake_echoicefield(), which does not exist
inechoices.fields. This will cause the Django server to crash, as
anAttributeError: module 'echoices.fields' has no attribute 'MyEnumNameField'exception will be raised.To prevent this, you have to edit the migration file and replace the
instantiation of the non-existing class with a call tomake_echoicefield(), with the same parameters as when defining the
field in your model.For example, assume you have the following model defined inmodels.py:from django.db import models
from echoices.fields import make_echoicefield

class MyModel(models.Model):
    state = make_echoicefield(EStates, default=EStates.CREATED)Then you would replace the generated field instantiation statement inmigrations/0001_initial.pymigrations.CreateModel(
    name='MyModel',
    fields=[
        # Replace the statement below
        ('state', echoices.fields.EStatesField(
                        echoices=app.models.EStates,
                        default=app.models.EStates(1))
        ),
    ],with('state', echoices.fields.make_echoicefield(
                echoices=app.models.EStates,
                default=app.models.EStates.CREATED)
),fields.MultipleEChoiceFieldSimilar to previous fields, but supports multiple values to be selected.**Not yet
implemented**.Usage in templatesAssume aContext(dict(estates=myapp.models.EStates))is provided to
the following templates.Fields of theEChoicecan be accessed in the templates as:{{ estates.CREATED.value }}
{{ estates.CREATED.label }}EChoicecan also be enumerated:{% for state in estates %}
    {{ state.value }}
    {{ state.label }}
{% endfor %}