I saw this thread so wanted to share a bit of a gotcha we had with enums internally for anyone trying to handle this stuff
Internally, we have a wrapper around CharField to work with enums (we go further than just choices and actually have the values be enums), but there's unfortunately still a good amount of issues in certain use cases that make it not a great fit to be put into general usage for Django. I do think it's possible to get things right, but you have to establish certain rules because the way enums work in Django can sometimes be surprising. We notably had an issue with translations, and I believe the problem would occur with other context-sensitive values. Because database operations will often copy values before using them to save to the database, you're beholden to (what I believe to be) slightly busted semantics on `copy.copy` for enums. Probably defining a django-y enum subclass that requires identity/lookup helpers would make this more usable for the general public (much like what other people have said). In [10]: from enum import Enum In [11]: from django.utils.translation import ugettext_lazy, override In [12]: class C(Enum): ...: a = ugettext_lazy("Some Word") In [13]: with override('en'): ...: elt = C.a ...: with override('ja'): ...: copy.copy(elt) ...: --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-13-9c36cbd82121> in <module> 2 elt = C.a 3 with override('ja'): ----> 4 copy.copy(elt) 5 /usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/copy.py in copy(x) 104 if isinstance(rv, str): 105 return x --> 106 return _reconstruct(x, None, *rv) 107 108 /usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy) 272 if deep and args: 273 args = (deepcopy(arg, memo) for arg in args) --> 274 y = func(*args) 275 if deep: 276 memo[id(x)] = y /usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/enum.py in __call__(cls, value, names, module, qualname, type, start) 289 """ 290 if names is None: # simple value lookup --> 291 return cls.__new__(cls, value) 292 # otherwise, functional API: we're creating a new Enum type 293 return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start) /usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/enum.py in __new__(cls, value) 531 return member 532 # still not found -- try _missing_ hook --> 533 return cls._missing_(value) 534 535 def _generate_next_value_(name, start, count, last_values): /usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/enum.py in _missing_(cls, value) 544 @classmethod 545 def _missing_(cls, value): --> 546 raise ValueError("%r is not a valid %s" % (value, cls.__name__)) 547 548 def __repr__(self): ValueError: 'Japanese Version of Some Word' is not a valid C -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at https://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/ad1b1890-3ce3-46fb-9801-6408de4ed256%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.