Establecer el valor seleccionado en un formulario de Django.

106

Aquí está la declaración de campo en un formulario:

max_number = forms.ChoiceField(widget = forms.Select(), 
    choices = ([('1','1'), ('2','2'),('3','3'), ]), initial='3', required = True,)

Me gustaría establecer el valor inicial 3y esto no parece funcionar. He jugado con el parámetro, comillas / sin comillas, etc. pero sin cambios.

¿Alguien podría darme una respuesta definitiva si es posible? ¿Y / o el ajuste necesario en mi fragmento de código?

Estoy usando Django 1.0

thebiglife
fuente
Me he estado preguntando lo mismo. "initial" tampoco parece funcionar con las opciones de la última versión del tronco.
Ty.

Respuestas:

114

Intente establecer el valor inicial cuando cree una instancia del formulario:

form = MyForm(initial={'max_number': '3'})
Tom
fuente
3
¿ '3'Corresponde al primer valor de la tupla o al segundo?
Bestasttung
4
las tuplas representan pares (valor, etiqueta) para las opciones y desea especificar el valor inicial, por lo que el '3' se refiere al primer elemento.
Tom
95

Esto no toca la pregunta inmediata en cuestión, pero esta Q / A surge para búsquedas relacionadas con tratar de asignar el valor seleccionado a un ChoiceField.

Si ya ha llamado super().__init__en su clase Form, debe actualizar el form.initialdiccionario, no la field.initialpropiedad. Si estudia form.initial(por ejemplo, print self.initialdespués de la llamada a super().__init__), contendrá valores para todos los campos. Tener un valor de Noneen ese dict anulará el field.initialvalor.

p.ej

class MyForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        # assign a (computed, I assume) default value to the choice field
        self.initial['choices_field_name'] = 'default value'
        # you should NOT do this:
        self.fields['choices_field_name'].initial = 'default value'
colinta
fuente
3
si no entiende esta respuesta, lea este formulario de django
gotchas
1
No estoy seguro de si es porque esta respuesta es tan antigua que ya no funciona, pero no puedo hacer que esta solución funcione. He probado todas las combinaciones de las anteriores y todavía no recibo amor. He vuelto a hacer esta pregunta aquí: stackoverflow.com/questions/52191096/… Si la respuesta sigue siendo la misma, avíseme cuál es el problema con mi código. ¡Gracias!
Lehrian
48

También puede hacer lo siguiente. en tu formulario class def:

max_number = forms.ChoiceField(widget = forms.Select(), 
                 choices = ([('1','1'), ('2','2'),('3','3'), ]), initial='3', required = True,)

luego, al llamar al formulario en su vista, puede establecer dinámicamente tanto las opciones iniciales como la lista de opciones.

yourFormInstance = YourFormClass()

yourFormInstance.fields['max_number'].choices = [(1,1),(2,2),(3,3)]
yourFormInstance.fields['max_number'].initial = [1]

Nota: los valores iniciales deben ser una lista y las opciones deben ser 2 tuplas, en mi ejemplo anterior tengo una lista de 2 tuplas. Espero que esto ayude.

Burton Williams
fuente
5
Quizás valga la pena señalar que el valor de se initialrefiere a la clave del elemento a seleccionar, no a su índice. ¡Me tomó un par de intentos resolver esto!
BigglesZX
20

También me encontré con este problema y descubrí que el problema está en el navegador. Cuando actualiza, el navegador vuelve a llenar el formulario con los mismos valores que antes, ignorando el campo marcado. Si ve la fuente, verá que el valor marcado es correcto. O coloque el cursor en el campo URL de su navegador y presione enter. Eso volverá a cargar el formulario desde cero.

Dave
fuente
1
solo para tu información, esto todavía sucede en FF6. Pulsar el botón de actualización no es suficiente. Sin embargo, en Google Chrome botón de actualización es suficiente, sin necesidad de ir a la barra de direcciones
MHD
1
Creo que siempre sucederá en Firefox; es el comportamiento previsto.
thepeer
Todavía sucede en Chrome 83, ¡me salvaste la vida!
lapin
7

Las respuestas de Tom y Burton me funcionan eventualmente, pero tuve un pequeño problema para averiguar cómo aplicarlas a un ModelChoiceField.

El único truco es que las opciones se almacenan como tuplas de (<model's ID>, <model's unicode repr>), por lo que si desea establecer la selección del modelo inicial, debe pasar la ID del modelo como valor inicial, no el objeto en sí, su nombre o cualquier otra cosa. Entonces es tan simple como:

form = EmployeeForm(initial={'manager': manager_employee_id})

Alternativamente, el initialargumento se puede ignorar en lugar de una línea adicional con:

form.fields['manager'].initial = manager_employee_id
Orlade
fuente
1
Su segunda línea de código funciona a la perfección en uno de esos raros casos en los que necesita establecer el valor inicial de un formulario después de una GETsolicitud y configurarlo desde una vista.
kstratis
3

Dave, ¿has tenido suerte para encontrar una solución al problema del navegador? ¿Hay alguna forma de forzar una actualización?

En cuanto al problema original, intente lo siguiente al inicializar el formulario:

def __init__(self, *args, **kwargs):
  super(MyForm, self).__init__(*args, **kwargs)   
  self.base_fields['MyChoiceField'].initial = initial_value

fuente
1
Esto no se ve muy bien. Citado de django 1.3, forms.py:93:Instances should always modify self.fields; they should not modify self.base_fields.
Tomas Tomecek
1

Para estar seguro, necesito ver cómo está renderizando el formulario. El valor inicial solo se usa de forma independiente, si está vinculado y no se incluye un valor para ese campo, no se seleccionará nada.

Andrew Wilkinson
fuente
-4

Prueba esto, funciona para mí, he agregado esto en models.py

options = (
    ('1','1'),
    ('2','2'),
    ('3','3')
)

max_number = forms.ChoiceField(max_length = 2, choices = options, default ='3')
abhijeetmote
fuente
6
Esto da un error en django 1.8.1: TypeError at /my/url/ __init__() got an unexpected keyword argument 'default' Request Method: GET Request URL: http://localhost:8000/my/url/ Django Version: 1.8.1 Exception Type: TypeError Exception Value: __init__() got an unexpected keyword argument 'default'
juliocesar