У меня был такой же зуд, и вот что я написал:
from django.db import models
from django.db.models.base import ModelBase
import re
class ModelBaseWithChoices(ModelBase):
def __new__(cls, name, bases, attrs):
def format_label(label):
return re.sub('[^A-Z]+', '_', label.upper()).strip('_')
def get_choices(attrs):
for attr, value in attrs.items():
if attr.endswith('_CHOICES') and isinstance(value, tuple):
base = '_'.join(attr.split('_')[:-1])
for val, label in value:
yield '_'.join((base, format_label(label))), val
attrs.update(list(get_choices(attrs)))
return super(ModelBaseWithChoices, cls).__new__(cls, name, bases, attrs)
class ModelWithChoices(models.Model):
__metaclass__ = ModelBaseWithChoices
class Meta:
abstract = True
Оттуда вы можете переписать MyModel
как:
class MyModel(ModelWithChoices):
BLAH_CHOICES = ((1, 'Foodally boogaly'),
(2, 'Bar bar bar bar'),
(3, 'Goo goo gaa gaa'))
blah = models.IntegerField(choices = BLAH_CHOICES)
И автоматически иметь все константысоздан для вас в модели.Из оболочки Джанго:
>>> MyModel.BLAH_FOODALLY_BOOGALY
1
>>> MyModel.BLAH_GOO_GOO_GAA_GAA
3