Package: django-enumfield
django-enumfieldProvides an enumeration Django model field (usingIntegerField) with reusable enums and transition validation.InstallationCurrently,we testDjango versions 2.2-4.1 and Python versions 3.7-3.11.Installdjango-enumfieldin your Python environment:$pipinstalldjango-enumfieldUpgrading from django-enumfield 1.x?See the migration guideFor use with Django versions prior to 1.8 use version1.2.1For use with Django versions prior to 1.11 use version1.5UsageCreate anEnum-class and pass it as first argument to the Django modelEnumField.fromdjango.dbimportmodelsfromdjango_enumfieldimportenumclassBeerStyle(enum.Enum):LAGER=0STOUT=1WEISSBIER=2classBeer(models.Model):style=enum.EnumField(BeerStyle,default=BeerStyle.LAGER)# Use .get to get enum values from either name or intsprint(BeerStyle.get("LAGER"))# <BeerStyle.LAGER: 0>print(BeerStyle.get(1))# <BeerStyle.STOUT: 1>print(BeerStyle.get(BeerStyle.WEISSBIER))# <BeerStyle.WEISSBIER: 2># It's also possible to use the normal enum way to get the valueprint(BeerStyle(1))# <BeerStyle.STOUT: 1>print(BeerStyle["LAGER"])# <BeerStyle.LAGER: 0># The enum value has easy access to their value and nameprint(BeerStyle.LAGER.value)# 0print(BeerStyle.LAGER.name)# "LAGER"For more information about Python 3 enums
(which ourEnuminherits,IntEnumto be specific)
checkout thedocs.Setting the default valueYou can also set default value on your enum class using__default__attributefromdjango.dbimportmodelsfromdjango_enumfieldimportenumclassBeerStyle(enum.Enum):LAGER=0STOUT=1WEISSBIER=2__default__=LAGERclassBeerStyleNoDefault(enum.Enum):LAGER=0classBeer(models.Model):style_default_lager=enum.EnumField(BeerStyle)style_default_stout=enum.EnumField(BeerStyle,default=BeerStyle.STOUT)style_default_null=enum.EnumField(BeerStyleNoDefault,null=True,blank=True)# When you set __default__ attribute, you can access default value via# `.default()` method of your enum classassertBeerStyle.default()==BeerStyle.LAGERbeer=Beer.objects.create()assertbeer.style_default_larger==BeerStyle.LAGERassertbeer.style_default_stout==BeerStyle.STOUTassertbeer.style_default_nullisNoneLabelsYou can use your own labels forEnumitemsfromdjango.utils.translationimportgettext_lazyfromdjango_enumfieldimportenumclassAnimals(enum.Enum):CAT=1DOG=2SHARK=3__labels__={CAT:gettext_lazy("Cat"),DOG:gettext_lazy("Dog"),}print(Animals.CAT.label)# "Cat"print(Animals.SHARK.label)# "SHARK"# There's also classmethods for getting the labelprint(Animals.get_label(2))# "Dog"print(Animals.get_label("DOG"))# "Dog"Validate transitionsTheEnum-class provides the possibility to use transition validation.fromdjango.dbimportmodelsfromdjango_enumfieldimportenumfromdjango_enumfield.exceptionsimportInvalidStatusOperationErrorclassPersonStatus(enum.Enum):ALIVE=1DEAD=2REANIMATED=3__transitions__={DEAD:(ALIVE,),# Can go from ALIVE to DEADREANIMATED:(DEAD,)# Can go from DEAD to REANIMATED}classPerson(models.Model):status=enum.EnumField(PersonStatus)# These transitions state that a PersonStatus can only go to DEAD from ALIVE and to REANIMATED from DEAD.person=Person.objects.create(status=PersonStatus.ALIVE)try:person.status=PersonStatus.REANIMATEDexceptInvalidStatusOperationError:print("Person status can not go from ALIVE to REANIMATED")else:# All goodperson.save()In formsTheEnum-class can also be used without theEnumField. This is very useful in Django formChoiceFields.fromdjangoimportformsfromdjango_enumfieldimportenumfromdjango_enumfield.forms.fieldsimportEnumChoiceFieldclassGenderEnum(enum.Enum):MALE=1FEMALE=2__labels__={MALE:"Male",FEMALE:"Female",}classPersonForm(forms.Form):gender=EnumChoiceField(GenderEnum)RenderingPersonFormin a template will generate a select-box with "Male" and "Female" as option labels for the gender field.Local Development EnvironmentMake sure black and isort is installed in your env withpip install -e .[dev].Before committing runmake formatto apply black and isort to all files.