2010-03-09 6 views
30

Estos conjuntos de formularios muestran exactamente el frente al comportamiento que yo quiero.Conjuntos de formularios de Django: ¿se requiere primero?

Mi opinión está configurado de esta manera:

def post(request): # TODO: handle vehicle formset 
    VehicleFormSetFactory = formset_factory(VehicleForm, extra=1) 
    if request.POST: 
     vehicles_formset = VehicleFormSetFactory(request.POST) 
    else: 
     vehicles_formset = VehicleFormSetFactory() 

Y mi plantilla es el siguiente:

<div id="vehicle_forms"> 
     {{ vehicles_formset.management_form }} 
     {% for form in vehicles_formset.forms %} 
      <h4>Vehicle {{forloop.counter}}</h4> 
      <table> 
       {% include "form.html" %} 
      </table> 
     {% endfor %} 
    </div> 

De esta manera se genera inicialmente sólo el 1 forma, como yo quiero. ¡Pero quiero que se requiera esa forma!

Cuando agrego dinámicamente formularios en blanco con JavaScript y vehicles_formset.empty_form se requieren todos esos formularios adicionales, que no quiero.

A partir de los documentos:

El juego de formularios es lo suficientemente inteligente como para ignorar las formas adicionales que no se han cambiado.

Este es el comportamiento que está mostrando la primera forma (no lo que quiero) pero no el comportamiento que exhiben las formas extra (lo que quiero).

¿Hay algún atributo que pueda cambiar para al menos hacer se requiere un formulario?

+0

@ MPes aunque estoy tarde a la fiesta, me preguntaba cómo ir sobre un tema ligeramente diferente que estoy enfrentando mi pregunta aquí (https://stackoverflow.com/questions/44159559/need-to-have-a-required-and-optional-fields-in-django-formset) – dungu

+0

@kedric Estas preguntando el chico equivocado No he usado Django desde poco después de publicar esta pregunta. – mpen

+0

ooh, Ok, amigo gracias por la respuesta – dungu

Respuesta

65

encontrado una mejor solución:

class RequiredFormSet(BaseFormSet): 
    def __init__(self, *args, **kwargs): 
     super(RequiredFormSet, self).__init__(*args, **kwargs) 
     for form in self.forms: 
      form.empty_permitted = False 

A continuación, cree que su juego de formularios de esta manera:

MyFormSet = formset_factory(MyForm, formset=RequiredFormSet) 

I realmente no sé por qué esto no era una opción para empezar .. . Pero lo que sea. Solo me tomó algunas horas de mi vida descubrirlo.

Esto hará que todos los formularios sean necesarios.Puede hacer solo el primero requerido configurando self.forms[0].empty_permitted en False.

+1

Esta es la solución a una de las partes más molestas de Django, es inexplicable por qué esto no forma parte de la documentación – YPCrumble

+0

Por algún motivo, obtengo un error de clave cuando intento establecer un formulario específico para empty_permitted. Por ejemplo, "form [0] .empty_permitted = False" da un error. –

+0

@Zorpix Debería ser 'self.forms [0]' Creo, suponiendo que tiene al menos un formulario. – mpen

1

Oh, creo que ya veo. Prueba esto:

from django.forms.formsets import BaseFormSet, formset_factory 
class OneExtraRequiredFormSet(BaseFormSet): 
    def initial_form_count(self): 
     return max(super(OneExtraRequiredFormSet,self).initial_form_count() - 1,0) 

VehicleFormSetFactory = formset_factory(VehicleForm, formset=OneExtraRequiredFormSet, extra=1) 

== == Respuesta original por debajo

Cuando se dice "por lo menos hacer una forma necesaria", supongo que te refieres "hacer sólo una forma extra que se requiere, independientemente de cuántos tienen sido agregado a través de javascript ".

Deberá tener una entrada oculta en su página que contenga el número de formularios que se han agregado mediante javascript y luego usar ese número, menos 1, como el valor para pasar como el atributo extra al constructor de sus conjuntos de formularios .

+0

No del todo ... ignorando el JavaScript por el momento, se muestra una y solo una forma (extra = 1, sin datos iniciales). Ese * one * formulario no es obligatorio, quiero que sea. Cualquier formulario agregado a través de JS no debe * ser * requerido, nunca. – mpen

+0

¿Mi edición ayuda? – Wogan

+0

Eso tiene un comportamiento extraño. Cuando dejo el formulario en blanco y lo presento, agrega otro y pone errores en el nuevo formulario, y aún no valida el primero. – mpen

9

Bueno ... esto hace que la primera forma sea necesaria.

class RequiredFormSet(BaseFormSet): 
    def clean(self): 
     if any(self.errors): 
      return 
     if not self.forms[0].has_changed(): 
      raise forms.ValidationError('Please add at least one vehicle.') 

único "problema" es que si hay 0 formas, a continuación, no parece que se llama en absoluto el método clean, así que no sé cómo comprobar si hay 0. En serio .. .pero esto nunca debería suceder (excepto que mi JS tiene un error, lo que le permite eliminar todos los formularios).

+1

Si usa este formulario para editar un conjunto existente de objetos, siempre se verá obligado a actualizar el primero. Esto solo es adecuado para la creación, no para la actualización. –

+0

@Daniel Palm, ¿tienes una solución? También tengo el mismo problema. –

Cuestiones relacionadas