2009-06-01 34 views
44

Estoy tratando de rellenar los datos en mi formulario django en base a cierta información, pero NO utilizando ModelForm, por lo que no puedo simplemente configurar la instancia.Formulario de Django de pre-llenado (no modelo)

Parece que debería ser realmente fácil, pero por alguna razón no encuentro ninguna documentación que me diga cómo hacerlo. Esta es mi forma:

class MyForm(forms.Form): 
    charfield1 = forms.CharField(max_length=3) 
    charfield2 = forms.CharField(max_length=3) 
    choicefield = forms.ModelChoiceField(MyModel.objects.all()) 

He intentado sólo hacer:

form = MyForm() 
form.charfield1 = "foo" 
form.charfield2 = "bar" 
# a model choice field 
form.choicefield = MyModel.objects.get(id=3) 

que no funciona.

Respuesta

79

Probar:

form = MyForm({'charfield1': 'foo', 'charfield2': 'bar'}) 

El constructor de objetos Form puede tomar un diccionario de valores de campo. Esto crea una forma enlazada, que puede usarse para validar los datos y representar el formulario como HTML con los datos mostrados. Consulte la documentación de the forms API para obtener más detalles.

Editar:

En aras de la exhaustividad, si no desea enlazar el formulario, y lo que desea declarar los valores iniciales de algunos campos, puede utilizar el siguiente lugar:

form = MyForm(initial={'charfield1': 'foo', 'charfield2': 'bar'}) 

Consulte la documentación de initial values para obtener más información.

+0

gracias - esto funciona. Sin embargo, no funciona con la clave externa de un modelo. Intenté pasar la instancia del modelo en el diccionario, lo que arroja una excepción, e intenté pasar el pk/id, que no falla, pero no lo precarga correctamente en la interfaz de usuario de mi formulario. – Cory

+0

El uso de la identificación del objeto debería funcionar. Acabo de probarlo con un ModelChoiceField. ¿Podría mostrarnos su definición de formulario? –

+0

agregó la definición del formulario en la edición. – Cory

23

Existen dos formas de rellenar un formulario de Django.

Lo primero es pasar un diccionario como primer argumento cuando lo crea (o lo pasa como data kwarg, que es lo mismo). Esto es lo que debes hacer cuando quieras usar datos POST para rellenar y validar el formulario.

data_dict = {'charfield1': 'data1', 'charfield2': 'data2', 'choicefield': 3} 
form = MyForm(data_dict) 

Sin embargo, esto dará lugar a la validación en el formulario, por lo que sólo funciona si en realidad se está pasando en datos válidos y completos para empezar - de lo contrario se comenzará con errores.

La otra forma de rellenar un formulario es utilizar el parámetro initial (documentado here). Esto proporciona valores iniciales para los campos de formulario, pero no no activa la validación. Por lo tanto, es adecuado si no está completando todos los valores, por ejemplo.

form = MyForm(initial=data_dict) 

para rellenar un choicefield través initial, utilice el valor pk.

+0

Basado en lo anterior, ¿cómo proporciona datos a los campos de formulario del cliente? – Chris

+0

@Chris, si tiene una pregunta y no está cubierta por lo anterior, abra una nueva pregunta y solicítela allí, con todos los detalles. –

+0

Fue una pregunta secundaria relacionada con esta respuesta. – Chris

12

Puede usar model_to_dict() para convertir una instancia a un diccionario y luego completar un formulario con eso. Algo como esto debería funcionar:

from django.forms.models import model_to_dict 
... 
my_obj = MyModel.objects.get(abc=123) 
form = MyForm(initial=model_to_dict(my_obj)) 

Nota: Estoy usando Django versión 1.3

1

Por lo que vale la pena, la FormView a base de clase de vista manera de hacer esto sería para anular el FormView 's get_initial función.get_initial devuelve los argumentos de palabras clave iniciales utilizados por get_form_kwargs para crear una instancia del formulario.

Docs:

  • para get_initial, here,
  • para get_form_kwargs, here.

Código de ejemplo:

from django.views.generic.edit import FormView 

class MyFormView(FormView): 

    def get_initial(self): 
     initial = super(MyFormView, self).get_initial() 
     # update initial field defaults with custom set default values: 
     initial.update({'charfield1': 'foo', 'charfield2': 'bar'}) 
     return initial 
Cuestiones relacionadas