I published my first package to PyPI today. Which is odd, considering that I've been developing stuff in Python for over a decade.
I decided, after doing a bunch of work on various projects, that I needed to scratch a particular Django-related, itch. Namely, that of choices:
MY_CHOICES = ( (0, "My Choice"), (1, "Another Choice"), (2, "A third choice), )
Choices have always bugged me, because they encourage you to do hard-coded stuff where you shouldn't be doing hard-coded stuff -- for example:
my_field = models.IntegerField(choices=MY_CHOICES, default=0)
If you ever change
MY_CHOICES you've then got to remember what hard-coded
nonsense you've got going on everywhere in your codebase. Of course, you could
MY_CHOICE_0 = 0 MY_CHOICE_1 = 1 MY_CHOICES = ( (MY_CHOICE_0, "My Choice 0"), (MY_CHOICE_1, "My Choice 1"), )
Which is better, but strikes me as somewhat annoying -- all that extra defining of constants.
django-useful-enums, which allows you to do this:
from usefulenums import Enum MyEnum = Enum( ("PYTHON_NAME_0", "Display text for this value"), ("PYTHON_NAME_1", "Display text for another value"), )
Looks the same, sure, but now you can do this:
>>> print(MyEnum.PYTHON_NAME_0) 0
Which means that you can use standard Python dot notation to access what have become under-the-hood constants:
my_field = models.IntegerField(default=MyEnum.PYTHON_NAME_0)
Still need choices? Okay, no worries, got you covered there too.
>>> print(MyEnum.as_choices()) ((0, "Display text for this value"), (1, "Display text for another value"))
And if you've got backwards-compatibility to care about, you can specify your
own IDs by passing a three-tuple instead of a two-tuple to
>>> MyEnum = Enum( ("A", "CHOICE_ALPHA", "A is for Alpha"), ("B", "CHOICE_BETA", "B is for Beeblebrox"), ) >>> print(MyEnum.as_choices()) (('A', 'A is for Alpha'), ('B', 'B is for Beeblebrox'))
You can get
django-useful-enums using pip:
pip install django-useful-enums
and you can find the source on Github.