Created
August 14, 2012 15:34
-
-
Save beniwohli/3350326 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# modified version of http://tomforb.es/using-python-metaclasses-to-make-awesome-django-model-field-choices | |
# that preserves order of definition | |
import inspect, itertools | |
class Option(object): | |
_counter = itertools.count() | |
def __init__(self, value, verbose_name=None): | |
self._count = Option._counter.next() | |
self.value = value | |
self.verbose_name = verbose_name if verbose_name is not None else value | |
def __repr__(self): | |
return "Field(%r)" % self.value | |
class ChoiceBase(type): | |
def __new__(cls, name, bases, attrs): | |
new_class = super(ChoiceBase, cls).__new__(cls, name, bases, attrs) | |
fields = [(key, value) for key, value in attrs.iteritems() if isinstance(value, Option)] | |
new_class._data = sorted(fields, key=lambda item: item[1]._count) | |
for field in fields: | |
setattr(new_class, field[0], field[1].value) | |
return new_class | |
def __iter__(self): | |
for value, data in self._data: | |
yield data.value, data.verbose_name | |
class Choice(object): | |
""" | |
Example: | |
class GenderChoice(Choice): | |
MALE = Option('male', _('male')) | |
FEMALE = Option('female', _('female')) | |
""" | |
__metaclass__ = ChoiceBase |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment