Well, I was wondering too, found some solutions on the Web but after all need some rewriting to came up with this:
class Enumeration(object): """ A small helper class for more readable enumerations, and compatible with Django's choice convention. You may just pass the instance of this class as the choices argument of model/form fields. Example: MY_ENUM = Enumeration([ (100, 'MY_NAME', 'My verbose name'), (200, 'MY_AGE', 'My verbose age'), ]) assert MY_ENUM.MY_AGE == 100 assert MY_ENUM[1] == (200, 'My verbose age') """ def __init__(self, enum_list): self.enum_list_full=enum_list self.enum_list = [(item[0], item[2]) for item in enum_list] self.enum_dict = {} self.enum_display = {} for item in enum_list: self.enum_dict[item[1]] = item[0] self.enum_display[item[0]] = item[2] def __contains__(self, v): return (v in self.enum_list) def __len__(self): return len(self.enum_list) def __getitem__(self, v): if isinstance(v, basestring): return self.enum_dict[v] elif isinstance(v, int): return self.enum_list[v] def __getattr__(self, name): return self.enum_dict[name] def __iter__(self): return self.enum_list.__iter__() def __repr__(self): return 'Enum(%s)' % self.enum_list_full.__repr__() def get_display_name(self, v): return self.enum_display[v]
This is a little customization of this snippet: http://djangosnippets.org/snippets/1647/
How does it work with models? Nice and easy:
class SoomeModel(models.Model): OPTIONS=Enumeration([ (1, OPTION_A, u'This is option A'), (2, OPTION_B, u'This is option B'), (3, OPTION_C, u'This is option C'), ]) option = models.IntegerField(choices=OPTIONS)
Now you can use it like that:
>> SomeModel.OPTIONS.OPTION_A .. 1 >> SomeModel.OPTIONS['OPTION_B'] .. 2 >> SomeModel.OPTIONS[1] .. (2, 'This is option B') >> SomeModel.OPTIONS.get_display_name(2) .. "This is option B" >> SomeModel.OPTIONS.get_display_name(SomeModel.OPTIONS_A) .. "This is option A"
No more hardcoding values. No more!
No comments:
Post a Comment