No consumo Django, pero sí algo parecido a la siguiente un poco debajo de la Pirámide y torció ...
def setup_mapping(pairs):
mapping = {'id':{},'name':{}}
for (k,v) in pairs:
mapping['id'][k]= v
mapping['name'][v]= k
return mapping
class ConstantsObject(object):
_pairs= None
mapping= None
@classmethod
def lookup_id(cls , id):
pass
@classmethod
def lookup_name(cls , name):
pass
class StatusConstants(ConstantsObject):
CANCELLED = -1
REQUIRES_ATTENTION = 0
WORK_IN_PROGRESS = 1
COMPLETE = 2
_pairs= (
(-1, 'Cancelled'),
(0, 'Requires attention'),
(1, 'Work in progress'),
(2, 'Complete'),
)
mapping= setup_mapping(_pairs)
Así que la esencia es la siguiente:
- Hay una base clase "constantes" y otra clase para cada tipo. la clase define las palabras clave a un valor en ALLCAPS
- Echo el texto sin formato
_pairs
en la clase también. ¿por qué? porque podría necesitar construir algunas tablas DB con ellas, o podría quererlas para mensajes de error/estado. Utilizo los números y no el nombre de la variable ALLCAPS como preferencia personal.
- i inicializar una variable
mapping
clase que básicamente monkeypatches la clase Precompilando un montón de variables dentro de un diccionario porque ...
- la clase se deriva de la clase base, que ofrece funcionalidad classmethod para buscar un valor o hacer otras cosas estándar que a menudo necesita hacer con constantes.
No es un enfoque único para todos, pero en general me gusta mucho. Puede usar fácilmente un dict para definir los pares, tiene la función 'mapeo' configurando otros atributos, tales como darle tuplas de los valores de par como k, v o v, k o cualquier formato extraño que pueda necesitar.
mi código puede entonces se parece a esto:
status_id = sa.Column(sa.Integer, sa.ForeignKey("_status.id") , nullable=False , default=constants.StatusConstants.CANCELLED)
status_name = constants.StatusConstants.lookup_id(status_id)
status_name = constants.StatusConstants.mapping['id'][status_id]
cada vez que necesite utilizar las constantes de otra manera, que acaba de añadir o alterar las classmethods de la base.
¿Has leído este interesante enfoque que usa '__metaclass__'? http://tomforb.es/using-python-metaclasses-to-make-awesome-django-model-field-choices –