2011-01-15 13 views
11

Dado un campo;Opciones de campo modelo Django: ¿no sería mejor un dict?

domain_status_choices = (
    (1,'Live') 
    (2,'Offline') 
    (3,'Dev') 
) 
status = models.SmallIntegerField(choices=domain_status_choices) 

Sé que puedo conseguir y representación numérica configurar y utilizar get_status_display() para obtener la etiqueta de texto. Pero si un usuario publica status=Offline, ¿cómo puedo obtener el valor numérico para guardarlo? También me gustaría poder validar que los números o valores de texto están en la lista.

Para mí tiene más sentido usar un dict. Aquí está mi método actual;

domain_status_choices = { 
    1: 'Live', 
    2: 'Offline', 
    3: 'Dev', 
} 
status = models.SmallIntegerField(choices=domain_status_choices.iteritems()) 
... 
if input1 not in domain_status_choices.keys(): print "invalid" 
if input2 not in domain_status_choices.items(): print "invalid" 
status = [k for k, v in domain_status_choices.iteritems() if v == input3][0] 

¿Hay una manera mejor? ¿Por qué se usa generalmente una tupla de tuplas?

+0

¿Ha intentado utilizar collections.OrderedDict para este caso de uso? (Para preservar el orden de las opciones) http://pymotw.com/2/collections/ordereddict.html –

Respuesta

13

Creo que las claves de un dict no están garantizadas para ser ordenadas (a menos que use OrderedDict obviamente). Es decir, puede "obtener" opciones de "Fuera de línea", "Dev", "En vivo" con su versión.

nota de Aplicación sobre dict.items:

claves y valores se enumeran en un orden arbitrario que es no aleatoria, varía a través de las implementaciones de Python, y depende de la historia del diccionario de inserciones y deleciones.

+0

Aquí hay un pensamiento, en mi caso con las teclas numéricas, ¿podría usar una lista? (no una lista de tuplas) O, si no estoy preocupado por el orden, podría seguir con este método. – Jake

+0

Gracias a la forma en que funciona Python, puedes construir lo que pases a las 'elecciones' de un campo como quieras. Si usa principalmente las opciones de alguna otra manera, no veo nada de malo en convertir esa lista/dict/lo que sea solo al pasarla al ' Campo (opciones =)' (es decir, si 'iteritems' le resulta útil, entonces esta bien). El punto es simple: Django supone que el orden de las elecciones no debe ser arbitrario. – vicvicvic

3

Ampliando mi comentario sobre la respuesta de @ vicvicvic:

t = [ 'Live', 'Offline', 'Dev', ] 
status = models.SmallIntegerField(choices=[(i,t[i]) for i in range(len(t))]) 
... 
if not 0 <= int(input1) < len(t): print "invalid" 
if input2 not in t: print "invalid" 
status = t.index(input2) 
+3

Use enumerate para subir la pitonica: '[(i, v) para i, v en enumerate (t)]' – TryPyPy

+4

¿Qué pasa con 'just enumerate (t)' – Jake

Cuestiones relacionadas