== Some notes on doing things with Django model formsets Django's model formsets are not well documented, at least not in the Django documentation I've found on their website. Oh, the API docs say more or less what parameters things like _[[modelformset_factory()|]]_ take, but they won't tell you how you should use them. In particular the documentation I've seen doesn't say very much about how to customize what appears in your form elements and so on. So here is what I know: The _form_ argument to _[[modelformset_factory()|]]_ is used to construct the class for individual form elements. It should inherit from _forms.ModelForm_ like regular customized forms, but unlike regular forms it should not have an internal _Meta_ class; the _Meta_ class (or its equivalent) will be added by the model formset construction process. Customized form classes can alter the default look and behavior of schema fields by defining form fields as usual, and they can also define validation and cleaning functions. Since form field validation is more powerful than schema field validation, you may want to override fields to, eg, make them into _forms.RegexField_ fields with appropriate regular expressions. Or just to improve the labels and error messages. (Yes, the need for this is a pain in the rear. If you want user friendly validation and error messages, you can wind up overriding nearly the entire set of model fields. Of course this pain exists for ordinary model forms as well.) The _formset_ argument to _[[modelformset_factory()|]]_ is used to construct the class for the overall formset. It should inherit from _BaseModelFormSet_ (from _django.forms.models_). What I have used this for is a _clean()_ method that makes sure that no two newly-created account requests have the same login. I believe that any _clean()_ function you use should start out by calling the superclass _clean()_. The _fields_ argument to _[[modelformset_factory()|]]_ is a list (in the broad sense) of what additional fields from the model should be included in the individual forms. Similarly, the _exclude_ argument is the list of what additional fields should be excluded. Note that this is *additional* fields; if you have a custom _form_ class, any fields it defines explicitly are always included. You do not need to list them in _fields_, and you cannot make them go away by listing them in _exclude_. If you need to include custom fields only some of the time, you will need multiple _form_ classes. Yes, this is annoying, especially if you have a lot of variants (and there may be a better way that involves more magic). (You can sort of see the implementation showing through here.) For future reference (given that Django changes over time), this is all applicable to Django 1.2.5. === Sidebar: how I find out what fields have changed in edited forms In a regular form (even a model form) you can inspect ((form.changed_data)) to see what fields have been edited. This is awkward to do in a modelformset, because you do not have convenient access to the individual forms that have been changed. How I get around this is the following, somewhat hacky code: > if formset.is_valid(): > instances = formset.save(commit=False) > cdict = dict(formset.changed_objects) > for thing in instances: > changed = cdict[thing] > .... (In [[my application DjangoORMDesignPuzzleII]] I need to take special action when various fields are modified, plus I like having audit records that say what fields were edited.)