public
Created

Python 3.4 Enums being used for Django Choices

  • Download Gist
models.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
import enum
 
 
class Choices(type(enum.Enum)):
 
def __new__(metacls, cls, bases, classdict):
temp = type(classdict)()
names = set(classdict._enum_names)
 
for k in classdict._enum_names:
v = classdict[k]
 
if v is Ellipsis:
v = k
 
if isinstance(v, (list, tuple)):
v = tuple([k if x is Ellipsis else x for x in v])
 
temp[k] = v
 
for k, v in classdict.items():
if k not in names:
temp[k] = v
 
# Add the __getitem__ we need to make this enum work for Django choices
if "__getitem__" not in temp:
temp["__getitem__"] = lambda self, idx: [self.value, self.display][idx]
 
if "__len__" not in temp:
temp["__len__"] = lambda self: 2
 
return super(Choices, metacls).__new__(metacls, cls, bases, temp)
 
@staticmethod
def _find_new(classdict, obj_type, first_enum):
def new(enum_class, db, display=None):
real_new, save_new, use_args = type(enum.Enum)._find_new(
classdict,
obj_type,
first_enum,
)
 
if not use_args:
enum_item = real_new(enum_class)
enum_item._value = db
else:
enum_item = real_new(enum_class, db)
if not hasattr(enum_item, "_value"):
enum_item._value = obj_type(db)
 
# Add the _display attribute
enum_item.display = display if display is not None else db
 
return enum_item
 
return new, False, True
 
 
class Contact(models.Model):
 
class Types(enum.Enum, metaclass=Choices):
author = ...
maintainer = "maintainer"
individual = ("individual", "Individual")
organisation = (..., "Organisation")
 
type = models.CharField(_("Type"), max_length=150, choices=Types)
 
name = models.TextField(_("Name"))
email = models.EmailField(_("Email"), max_length=254, blank=True)
url = URLTextField(_("URL"), blank=True)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.