2010-12-19 11 views
9

Tengo un pequeño problema con el formset.Django y formularios vacíos son válidos

Debo mostrar varios conjuntos de formularios en una página, y cada formset tiene varias formas. así que hice algo por el estilo:

#GET 
for prod in products: 
    ProductFormSet = modelformset_factory(Product,exclude=('date',),extra=prod.amount) 
    formsset.append(ProductFormSet(prefix="prod_%d"%prod.pk)) 

#POST 
for prod in products: 
    ProductFormSet = modelformset_factory(Product,exclude=('date',),extra=prod.amount) 
    formsset.append(ProductFormSet(request.POST,prefix="prod_%d"%prod.pk)) 

El problema es cuando envío a la página, las formas desocupa son 'automáticamente' válida (sin control), pero si completo un campo en una forma, el cheque trabaja en eso

No sé por qué, así que si alguien tiene una idea,

gracias.

Respuesta

19

Me encontré con esta pregunta mientras investigaba otro problema. Mientras buscaba en la fuente de Django una solución para mi problema, encontré la respuesta a esta pregunta, así que la documentaré aquí:

Cuando se permite que un formulario tenga valores vacíos (esto se aplica a los formularios vacíos que contiene dentro de un formset) y los valores enviados no se han cambiado desde los iniciales, la validación se omite. Compruebe el método de full_clean() en Django/formas/forms.py (línea 265 en Django 1.2):

# If the form is permitted to be empty, and none of the form data has 
# changed from the initial data, short circuit any validation. 
if self.empty_permitted and not self.has_changed(): 
    return 

No estoy seguro de qué tipo de solución que está buscando (también, esta cuestión ya está algo anticuado) pero tal vez esto ayudará a alguien en el futuro.

+0

Gracias, utilicé su solución para resolver mi problema: los formularios vacíos NO deberían validar. Ver mi ejemplo. –

2

Los formularios creados en base al parámetro "extra" de "formset_factory" tienen su propiedad "empty_permitted" establecida en True. (Ver: Línea formset.py 123)

# Allow extra forms to be empty. 
    if i >= self.initial_form_count(): 
     defaults['empty_permitted'] = True 

por lo que parece la mejor manera de utilizar el parámetro "inicial" de la FormSet y no el parámetro "extra" de "formset_factory" para este caso de uso.

puede encontrar la descripción en using-initial-data-with-a-formset

10

@Jonas, gracias. Usé tu descripción para resolver mi problema. Necesitaba un formulario para NO validar cuando estaba vacío. (Formularios agregados con javascript)

class FacilityForm(forms.ModelForm): 
    class Meta: 
     model = Facility 

    def __init__(self, *arg, **kwarg): 
     super(FacilityForm, self).__init__(*arg, **kwarg) 
     self.empty_permitted = False 


facility_formset = modelformset_factory(Facility, form=FacilityForm)(request.POST) 

Se asegurará de que los formularios mostrados no estén vacíos cuando se envíen.

+1

Dado que 'empty_permitted' es un argumento en el método __init__, puede usar' form_kwargs' en su llamada y evitar crear su método __init__ en su ejemplo de subclase. 'facility_formset = modelformset_factory (Facility, form = FacilityForm) (request.POST, form_kwargs = {'empty_permitted': False})' – Bobort

+0

Tenga en cuenta que form_kwargs está disponible en django versión 1.9+ –

Cuestiones relacionadas