2010-12-19 15 views
9

Mam mały problem z zestawem.Django i pusty zestaw są ważne.

Muszę wyświetlić kilka formularzy na stronie, a każdy zestaw ma kilka formularzy. więc zrobiłem coś takiego:

#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)) 

Problem jest, gdy przesłać na stronę, formy Butelki są „automatycznie” ważny (bez kontroli), ale gdybym wypełnić jedno pole w jednej formie, czek działa na nim.

Nie wiem dlaczego, więc jeśli ktoś ma pomysł,

dzięki.

Odpowiedz

19

Wpadłem na to pytanie podczas badania innego problemu. Podczas przeszukiwania źródła Django w poszukiwaniu rozwiązania mojego problemu, znalazłem odpowiedź na to pytanie, więc opiszę to tutaj:

Kiedy formularz może mieć puste wartości (dotyczy to pustych formularzy w obrębie zestawu) i przesłane wartości nie zostały zmienione od wartości początkowych, sprawdzanie poprawności jest pomijane. Sprawdź metodę full_clean() w django/forms/forms.py (line 265 w 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 

Nie jestem pewien, jakiego rodzaju rozwiązanie szukasz (również ta kwestia jest już nieco przestarzały), ale może to pomoże komuś w przyszłości.

+0

Dzięki, użyłem twojego rozwiązania, aby rozwiązać mój problem: Puste formularze NIE powinny się sprawdzać. Zobacz mój przykład. –

2

Formularze utworzone na podstawie "dodatkowego" parametru "formset_factory" mają ustawioną właściwość "empty_permitted" na wartość True. (Patrz: formset.py linię 123)

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

Wydaje się więc lepszy sposób na wykorzystanie „początkowy” parametr formset a nie „ekstra” parametr „formset_factory” dla tego przypadku użycia.

Proszę znaleźć opis w using-initial-data-with-a-formset

10

@Jonas, dzięki. Użyłem Twojego opisu, aby rozwiązać mój problem. Potrzebowałem formularza do sprawdzenia, czy jest pusty. (Formularze dodane z 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) 

Upewni się, że wszystkie wyświetlane formularze nie mogą być puste, gdy zostaną przesłane.

+1

Ponieważ 'empty_permitted' jest argumentem w metodzie __init__, możesz użyć' form_kwargs' w swoim wywołaniu i unikać tworzenia metody __init__ w swoim przykładzie podklasy. 'facility_formset = modelformset_factory (Facility, form = FacilityForm) (request.POST, form_kwargs = {'empty_permitted': False})' – Bobort

+0

Zauważ, że form_kwargs jest dostępny w wersji django 1.9+ –

Powiązane problemy