Cómo usar correctamente la opción del campo “opciones” en Django

Estoy leyendo el tutorial aquí: https://docs.djangoproject.com/en/1.5/ref/models/fields/#choices y estoy tratando de crear un cuadro donde el usuario puede seleccionar el mes en que nació Lo que intenté fue

MONTH_CHOICES = ( (JANUARY, "January"), (FEBRUARY, "February"), (MARCH, "March"), .... (DECEMBER, "December"), ) month = CharField(max_length=9, choices=MONTHS_CHOICES, default=JANUARY) 

¿Es esto correcto? Veo que en el tutorial que estaba leyendo, por alguna razón crearon primero las variables, como así

 FRESHMAN = 'FR' SOPHOMORE = 'SO' JUNIOR = 'JR' SENIOR = 'SR' 

¿Por qué crearon esas variables? Además, MONTHS_CHOICES se encuentra en un modelo llamado Personas, así que el código que proporcioné crearía una columna de “Opciones de meses” en la base de datos llamada “Personas” y diría en qué mes nació el usuario después de hacer clic en los meses. y envía el formulario?

Según la documentación :

Campo.Elecciones

Un iterable (por ejemplo, una lista o tupla) que consta de iterables de exactamente dos elementos (por ejemplo, [(A, B), (A, B) …]) para usar como opciones para este campo. Si se proporciona, el widget de formulario predeterminado será un cuadro de selección con estas opciones en lugar del campo de texto estándar.

El primer elemento de cada tupla es el valor real que debe almacenarse, y el segundo elemento es el nombre legible para el ser humano.

Entonces, su código es correcto, excepto que debería definir las variables JANUARY , FEBRUARY , etc. o usar el módulo de calendar para definir MONTH_CHOICES :

 import calendar ... class MyModel(models.Model): ... MONTH_CHOICES = [(str(i), calendar.month_name[i]) for i in range(1,13)] month = CharField(max_length=9, choices=MONTHS_CHOICES, default='1') 

Creo que en realidad nadie ha respondido a la primera pregunta:

¿Por qué crearon esas variables?

Esas variables no son estrictamente necesarias. Es verdad. Se puede hacer perfectamente algo como esto:

 MONTH_CHOICES = ( ("JANUARY", "January"), ("FEBRUARY", "February"), ("MARCH", "March"), # .... ("DECEMBER", "December"), ) month = models.CharField(max_length=9, choices=MONTH_CHOICES, default="JANUARY") 

¿Por qué usar variables es mejor? Prevención de errores y separación lógica.

 JAN = "JANUARY" FEB = "FEBRUARY" MAR = "MAR" # (...) MONTH_CHOICES = ( (JAN, "January"), (FEB, "February"), (MAR, "March"), # .... (DEC, "December"), ) 

Ahora, imagine que tiene una vista donde crea una nueva instancia de Modelo. En lugar de hacer esto:

 new_instance = MyModel(month='JANUARY') 

Harás esto:

 new_instance = MyModel(month=MyModel.JAN) 

En la primera opción estás codificando el valor. Si hay un conjunto de valores que puede ingresar, debe limitar esas opciones al codificar. Además, si finalmente necesita cambiar el código en la capa Modelo, ahora no necesita hacer ningún cambio en la capa Vistas.

No puede tener palabras simples en el código, esa es la razón por la que crearon variables (su código fallará con NameError ).

El código que proporcionó crearía una tabla de base de datos llamada month (más el prefijo que django agregue a eso), porque ese es el nombre del CharField .

Pero hay mejores formas de crear las elecciones particulares que deseas. Ver una pregunta anterior de desbordamiento de stack .

 import calendar tuple((m, m) for m in calendar.month_name[1:]) 

La solución más limpia es usar la biblioteca django-model-utils :

 from model_utils import Choices class Article(models.Model): STATUS = Choices('draft', 'published') status = models.CharField(choices=STATUS, default=STATUS.draft, max_length=20) 

https://django-model-utils.readthedocs.io/en/latest/utilities.html#choices