2012-08-12 12 views
13

Estoy luchando para conseguir mi cabeza alrededor de las formas django .. He estado leyendo varios documentos pero simplemente no logro captar los conceptos. Tengo que lidiar con modelos, vistas y plantillas. Lo que intento hacer es crear un formulario con varios campos que compongan listas desplegables y casillas de verificación que están pobladas por valores en una base de datos.creando formas de django

Tengo una aplicación que funciona llamada vms. Usando models.py he creado un esquema simple que contiene el tamaño y el tipo. El tamaño consiste en 'pequeño', 'medio' & 'grande'. Tipo es 'windows' & 'linux'. Utilizando el sitio de administración, puedo agregar un tamaño extra, por ejemplo 'Extra grande'.

Lo que me gustaría hacer es crear un formulario que tenga una lista desplegable de los tamaños de vm. Si se agrega un tamaño extra a través del sitio de administración, me gustaría que ese tamaño aparezca en la lista desplegable.

Enviaría mis intentos al código, pero en realidad estoy luchando con los conceptos. ¿Alguien puede ayudarme a guiarme en cómo lograr lo anterior?

Gracias Oli

+2

lea el tutorial https://docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs/ y https://docs.djangoproject.com/en/dev/topics/forms/?from = olddocs –

+0

He visto estos dos artículos y volveré a leerlos. Esperaba comprender las relaciones entre formularios, vistas y plantillas, y cómo crear una lista desplegable. Supongo que tal vez solo me lleve tiempo para digerir ... si alguien más puede dedicar algo de tiempo a explicar esto, ¡sería muy feliz! – Oli

Respuesta

30

Los formularios son solo una herramienta para simplificar y acelerar (el desarrollo de) el proceso de obtención de datos POST de la solicitud. Una forma manual sería hacer request.POST.get('somefield') para todos los campos que hay en algún formulario HTML. Pero Django puede hacer mejor que eso ...

En su esencia, una clase de formulario tiene una serie de campos y lleva a cabo estas tareas: entradas HTML

  1. de visualización,
  2. recopilar y validar los datos cuando el usuario lo somete,
  3. si los campos no validan, devuelven los valores junto con los mensajes de error en HTML,
  4. si todos los campos validan, proporcionan form.cleaned_data diccionario como una manera conveniente de acceder a estos valores a la vista.

Con estos valores, podría crear manualmente una nueva instancia de MyModel y guardarla. Por supuesto, tendría que definir un campo en el formulario para cada campo en el modelo de MyModel.

Esto significa que, básicamente, me podía hacer algo como esto:
(perdóname por no probar este código, así que no puedo dar fe de que es 100% correcto)

models.py: 

    class MyModel(models.Model): 
     field1 = models.CharField(max_length=40, blank=False, null=False) 
     field2 = models.CharField(max_length=60, blank=True, null=True) 

forms.py: 

    class FormForMyModel(forms.Form): 
     form_field1 = forms.CharField(max_length=40, required=True) 
     form_field2 = forms.CharField(max_length=60, required=False) 

views.py: 

    def create_a_my_model(request): 
     if request.method == 'POST': 
      form = FormForMyModel(request.POST) 
      if form.is_valid(): 
       my_model = MyModel() 
       my_model.field1 = form.cleaned_data.get('form_field1', 'default1') 
       my_model.field2 = form.cleaned_data.get('form_field2', 'default2') 
       my_model.save() 
     else:   
      form = FormForMyModel() 
     context_data = {'form': form} 
     return HttpResponse('templtate.html', context_data) 

(esto podría escribirse con unas pocas líneas de código menos, pero debe ser lo más claro posible)

¡Observe que no hay relación entre los Campos del modelo y los Campos del formulario! Tenemos que asignar manualmente valores a la instancia de MyModel al crearlo.

El ejemplo anterior describe el flujo de trabajo de formulario genérico. A menudo se necesita en situaciones complejas, pero no en una tan simple como es este ejemplo.

Para este ejemplo (y un montón de ejemplos del mundo real), Django puede hacer mejor que eso ...

Se puede notar dos cuestiones molestas en el ejemplo anterior:

  1. tengo para definir los campos en MyModel y los campos en FormForMyModel por separado. Sin embargo, hay una gran similitud entre esos dos grupos (tipos) de campos, por lo que es una especie de trabajo duplicado. La similitud aumenta cuando se agregan etiquetas, validadores, etc.
  2. creación de la instancia MyModel es un poco tonto, tener que asignar todos esos valores manualmente.

Aquí es donde un ModelForm entra en acción.

Estos actúan básicamente como una forma regular (en realidad, que se extendieron a partir de formas regulares), pero que me puede salvar algunos de los trabajos (Los dos problemas que acabo de delinear, por supuesto :)).

Así que de vuelta a las dos cuestiones:

  1. En lugar de definir un formulario de campo para cada modelo de campo, simplemente definen en el model = MyModel la clase Meta. Esto instruye al formulario para que genere automáticamente campos de formulario a partir de los campos del modelo.

  2. Las formas del modelo tienen save método disponible. Esto se puede usar para crear una instancia de modelo en una línea en la vista, en lugar de asignarlo campo por campo manualmente.

Por lo tanto, vamos a hacer el ejemplo anterior con un ModelForm:

models.py: 

    class MyModel(models.Model): 
     field1 = models.CharField(max_length=40, blank=False, null=False) 
     field2 = models.CharField(max_length=60, blank=True, null=True) 

forms.py: 

    class MyModelForm(forms.ModelForm): # extending ModelForm, not Form as before 
     class Meta: 
      model = MyModel 

views.py: 

    def create_a_my_model(request): 
     if request.method == 'POST': 
      form = MyModelForm(request.POST) 
      if form.is_valid(): 
       # save the model to database, directly from the form: 
       my_model = form.save() # reference to my_model is often not needed at all, a simple form.save() is ok 
       # alternatively: 
       # my_model = form.save(commit=False) # create model, but don't save to database 
       # my.model.something = whatever # if I need to do something before saving it 
       # my.model.save() 
     else:   
      form = MyModelForm() 
     context_data = {'form': form} 
     return HttpResponse('templtate.html', context_data) 

la esperanza que esto aclare el uso de Django forma un poco.

Una nota más: está perfectamente bien definir Campos de formulario en ModelForm. Estos no se usarán en form.save(), pero aún se puede acceder con form.cleaned_data como en un formulario regular.

+0

Hola, gracias por tu publicación. Voy a probar esto ahora mismo y me pondré en contacto contigo con el progreso. De hecho, noté que tu publicación es similar a la documentación que leí, pero has incluido algunos ejemplos claros. Esto definitivamente ayudará a ponerlo todo junto ... Esperemos que llegue pronto. – Oli

+1

Hola, tengo mis formularios trabajando ahora ... Sobre el primer obstáculo, gracias por tu ayuda. Junto con los ejemplos presentes en esta pregunta, docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs y docs.djangoproject.com/en/dev/topics/forms/?from=olddocs y este sitio, peachybits.com/2011/09/django-1-3-form-api-modelform-example Pude resolverlo. – Oli

2

¿Usted ha intentado trabajar con ModelForms antes? Según tengo entendido, estás buscando crear un formulario basado en el modelo que creaste, ¿verdad?

Digamos que su modelo se llama Temp. Puede crear un formulario que se correlaciona con este modelo (y su pregunta) como esto:

forms.py

from django.forms import ModelForm 

class TempForm(ModelForm): 
    class Meta: 
    model = Temp 

El ModelForm asignará automáticamente la selección/elección de su modelo para una versión formulario.

Si usted planea usar esto en una plantilla más tarde, haciendo algo como esto creará automáticamente un menú desplegable con opciones:

<form> 
    <label for="id_size">Size</label> 
    {{ form.size }} 
</form> 

esperanza de que responda a su pregunta!

+1

Gracias por su respuesta ... Trataré de probar esto. De hecho, me encontré con este sitio, http://www.peachybits.com/2011/09/django-1-3-form-api-modelform-example/, aunque es django 1.3, puedo ver los conceptos que se utilizan. Regresaré contigo cuando haya entendido tu ejemplo. Solo superar el obstáculo inicial parece difícil, pero una vez que lo tengo, estoy seguro de que fluirá fácilmente. – Oli

+0

Hola, tengo mis formularios funcionando ahora ... Sobre el primer obstáculo, gracias por tu ayuda. Junto con los ejemplos presentes en esta pregunta, docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs y docs.djangoproject.com/en/dev/topics/forms/?from=olddocs y este sitio, peachybits.com/2011/09/django-1-3-form-api-modelform-example Pude resolverlo. – Oli

Cuestiones relacionadas