Hi, Every Form subclass defines a method called 'is_valid()', even the FormSet has one, which will repeatedly call it on every form. After running is_valid(), form.cleaned_data will contain cleaned data from the forms.
On subclasses of FormSet you can also override the clean method, which allows you to do validation that depends on multiple forms, for example making sure the same day is not reported twice, etc. See http://docs.djangoproject.com/en/dev/topics/forms/formsets/#custom-formset-validation Rewriting your view to take advantage of this, as well as a nice idioms: def my_view(...): formset = FormsetFactory(request.POST or None) if formset.is_valid(): for form in formset.forms: if form.cleaned_data['should_save']: # save stuff here return redirect(my_other_view) return render_to_response('template', { 'formset': formset }) Replace with meaningful variables specific to your forms and models. As a side note, every subclass of Form allows overriding the clean method for doing custom validation. This can be extremely helpful in cases like this, as you can move complex logic from your view, into the forms which have access to everything. As another side note, you mentioned in the comment to pause that you actually want to store a timedelta. See this snippet for a Field which does exactly that: http://djangosnippets.org/snippets/1060/ See the following SO question for how to do it yourself: http://stackoverflow.com/questions/801912/how-to-put-timedelta-in-django-model Regards Knut On Mon, Nov 8, 2010 at 6:48 PM, Carsten Fuchs <carstenfu...@t-online.de> wrote: > Hi all, > > my name is Carsten Fuchs, and this is my first post here. I'm normally a C++ > developer for Windows and Linux desktop and server applications, and have > begun my first (big) database-web project in mid summer. Let me start with > saying that Django is utterly awesome: I've been able to complete a very > large part of this project in very short time, reading the excellent Django > online documentation and the Django online book. A huge thanks to everyone > who is involved! > > My Django application is for recording and managing the work hours of the > staff of a company with about 1000 employees, implemented on Ubuntu 10.04 > with Django 1.2, Python 2.6, Apache2 as webserver, and an Oracle 10g > database. > > My question is about validating the formset that is used for editing the > work hours (but I'm happy about all comments on whatever strikes you odd in > the code below ;-) ). > > > The main model is (slightly simplified for clarity): > > # This model should really be named "Workday", not "Erfasst". > class Erfasst(models.Model): > key = models.ForeignKey(Mitarbeiter, db_column='key', to_field='key') > datum = models.DateField() > anfang = models.TimeField() # Begin of work. > ende = models.TimeField() # End of work. > pause = models.CharField(max_length=8, blank=True) # (Need a > timedelta field...) > > > I wrote a view with a formset for editing the work hours in the above model > of an entire week or month. The form is: > > class ErfasseZeitForm(forms.Form): > # ID of "Erfasst" entry, if present in database. > ErfasstID = forms.IntegerField(required=False, > widget=forms.HiddenInput()) > > # We must pass the date for days that are not yet mentioned in the > database. > Datum = forms.DateField(widget=forms.HiddenInput()) > > # Begin, end, and pause of work. > Anfang = forms.TimeField(required=False) > Ende = forms.TimeField(required=False) > Pause = forms.TimeField(required=False) > > # A checkbox for "Save this form?" (which is part of a formset that > covers an entire month) > Speichern = forms.BooleanField(required=False) > > > Some notes about this form and the derived formset: > - We do not have data in table "Erfasst" for every day in the month, e.g. > Sundays or days in the future are usually not present, but the Formset is > still expected to have forms with empty data for such days. > - We do not use a ModelForm, so that we can have additional form fields > that have no correspondence in the model, such as "Speichern" above. > > At <http://www.cafu.de/files/temp/LoriScreenshot.png> I've uploaded a > screenshot of how the form renders, with default data for days in the > future, and the "Save?" checkbox that the user can use to have his changes > saved into the database or not. > (The full, current source code of the view is at > <http://pastebin.com/URDiua1D>.) > > > Now, here is the real question: > How do I properly validate this formset? > I want to consider (validate and save) only those forms in the format whose > "Save?" checkbox is set. > > In order words, is this code good Django practice? > > if request.method == 'POST': > ErfasseZeitenFormSet = ErfasseZeitenFormSetFactory(request.POST) > > IsFormsetValid = True > for Form in ErfasseZeitenFormSet.forms: > # Why does the call to clean() raise "'BoundField' object has no > attribute 'clean'"? > # Principally, is this right? good practice? > if Form['Speichern'].clean() and not Form.is_valid(): > IsFormsetValid = False > > if IsFormsetValid: > for Form in ErfasseZeitenFormSet.forms: > if Form['Speichern'].cleaned_data: > # TODO: Process the record specified in Form.cleaned_data > pass > > # Redirect after POST, so that the request isn't repeated when > the user hits "Refresh". > return HttpResponseRedirect('/lori/arbeitszeiten/%s/' % MA.key) > > else: > # ... > > > While writing this mail I found that the above code doesn't even work, > because "'BoundField' object has no attribute 'clean'". How do I do this > properly? > > I'd be very happy and grateful for any related feed-back and advice. > > Thank you very much, and best regards, > Carsten > > > > -- > Cafu - the open-source Game and Graphics Engine > for multiplayer, cross-platform, real-time 3D Action > Learn more at http://www.cafu.de > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-us...@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-users?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.