Skip to content

Instantly share code, notes, and snippets.

@agusmakmun
Created October 6, 2021 07:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agusmakmun/192c5f3f9ec630b7e04f46192321aaf6 to your computer and use it in GitHub Desktop.
Save agusmakmun/192c5f3f9ec630b7e04f46192321aaf6 to your computer and use it in GitHub Desktop.
import operator
from collections import OrderedDict
from django.utils.translation import gettext_lazy as _
class EnumMetaClass(type):
def __init__(cls, name, bases, classdict):
def _human_enum_values(enum):
return cls.__choices__[enum]
# add a class attribute
cls.humanize = _human_enum_values
@classmethod
def __prepare__(cls, name, bases):
return OrderedDict()
def __new__(cls, name, bases, classdict):
members = []
keys = {}
choices = OrderedDict()
for key, value in classdict.items():
if key.startswith("__"):
continue
members.append(key)
if isinstance(value, tuple):
value, alias = value
keys[alias] = key
else:
alias = None
keys[alias or key] = key
choices[alias or key] = value
for k, v in keys.items():
classdict[v] = k
classdict["__choices__"] = choices
classdict["__members__"] = members
# Note: Differences between Python 2.x and Python 3.x force us to
# explicitly use unicode here, and to explicitly sort the list. In
# Python 2.x, class members are unordered and so the ordering will
# vary on different systems based on internal hashing. Without this
# Django will continually require new no-op migrations.
classdict["choices"] = tuple(
(str(k), str(v))
for k, v in sorted(choices.items(), key=operator.itemgetter(0))
)
return type.__new__(cls, name, bases, classdict)
class Enum(metaclass=EnumMetaClass):
pass
class APIKeyType(Enum):
"""
API Key Types (internal model only)
"""
publishable = _("Publishable key")
secret = _("Secret key")
restricted = _("Restricted key")
...
class Foobar(models.Model):
status = models.CharField(
max_length=20,
choices=APIKeyType.choices,
default=APIKeyType.secret
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment