parts/django/docs/topics/forms/modelforms.txt
changeset 307 c6bca38c1cbf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/parts/django/docs/topics/forms/modelforms.txt	Sat Jan 08 11:20:57 2011 +0530
@@ -0,0 +1,885 @@
+==========================
+Creating forms from models
+==========================
+
+.. module:: django.forms.models
+   :synopsis: ModelForm and ModelFormset.
+
+.. currentmodule:: django.forms
+
+``ModelForm``
+=============
+.. class:: ModelForm
+
+If you're building a database-driven app, chances are you'll have forms that
+map closely to Django models. For instance, you might have a ``BlogComment``
+model, and you want to create a form that lets people submit comments. In this
+case, it would be redundant to define the field types in your form, because
+you've already defined the fields in your model.
+
+For this reason, Django provides a helper class that let you create a ``Form``
+class from a Django model.
+
+For example::
+
+    >>> from django.forms import ModelForm
+
+    # Create the form class.
+    >>> class ArticleForm(ModelForm):
+    ...     class Meta:
+    ...         model = Article
+
+    # Creating a form to add an article.
+    >>> form = ArticleForm()
+
+    # Creating a form to change an existing article.
+    >>> article = Article.objects.get(pk=1)
+    >>> form = ArticleForm(instance=article)
+
+Field types
+-----------
+
+The generated ``Form`` class will have a form field for every model field. Each
+model field has a corresponding default form field. For example, a
+``CharField`` on a model is represented as a ``CharField`` on a form. A
+model ``ManyToManyField`` is represented as a ``MultipleChoiceField``. Here is
+the full list of conversions:
+
+    ===============================  ========================================
+    Model field                      Form field
+    ===============================  ========================================
+    ``AutoField``                    Not represented in the form
+
+    ``BigIntegerField``              ``IntegerField`` with ``min_value`` set
+                                     to -9223372036854775808 and ``max_value``
+                                     set to 9223372036854775807.
+
+    ``BooleanField``                 ``BooleanField``
+
+    ``CharField``                    ``CharField`` with ``max_length`` set to
+                                     the model field's ``max_length``
+
+    ``CommaSeparatedIntegerField``   ``CharField``
+
+    ``DateField``                    ``DateField``
+
+    ``DateTimeField``                ``DateTimeField``
+
+    ``DecimalField``                 ``DecimalField``
+
+    ``EmailField``                   ``EmailField``
+
+    ``FileField``                    ``FileField``
+
+    ``FilePathField``                ``CharField``
+
+    ``FloatField``                   ``FloatField``
+
+    ``ForeignKey``                   ``ModelChoiceField`` (see below)
+
+    ``ImageField``                   ``ImageField``
+
+    ``IntegerField``                 ``IntegerField``
+
+    ``IPAddressField``               ``IPAddressField``
+
+    ``ManyToManyField``              ``ModelMultipleChoiceField`` (see
+                                     below)
+
+    ``NullBooleanField``             ``CharField``
+
+    ``PhoneNumberField``             ``USPhoneNumberField``
+                                     (from ``django.contrib.localflavor.us``)
+
+    ``PositiveIntegerField``         ``IntegerField``
+
+    ``PositiveSmallIntegerField``    ``IntegerField``
+
+    ``SlugField``                    ``SlugField``
+
+    ``SmallIntegerField``            ``IntegerField``
+
+    ``TextField``                    ``CharField`` with
+                                     ``widget=forms.Textarea``
+
+    ``TimeField``                    ``TimeField``
+
+    ``URLField``                     ``URLField`` with ``verify_exists`` set
+                                     to the model field's ``verify_exists``
+
+    ``XMLField``                     ``CharField`` with
+                                     ``widget=forms.Textarea``
+    ===============================  ========================================
+
+
+.. versionadded:: 1.0
+    The ``FloatField`` form field and ``DecimalField`` model and form fields
+    are new in Django 1.0.
+
+.. versionadded:: 1.2
+    The ``BigIntegerField`` is new in Django 1.2.
+
+
+As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field
+types are special cases:
+
+    * ``ForeignKey`` is represented by ``django.forms.ModelChoiceField``,
+      which is a ``ChoiceField`` whose choices are a model ``QuerySet``.
+
+    * ``ManyToManyField`` is represented by
+      ``django.forms.ModelMultipleChoiceField``, which is a
+      ``MultipleChoiceField`` whose choices are a model ``QuerySet``.
+
+In addition, each generated form field has attributes set as follows:
+
+    * If the model field has ``blank=True``, then ``required`` is set to
+      ``False`` on the form field. Otherwise, ``required=True``.
+
+    * The form field's ``label`` is set to the ``verbose_name`` of the model
+      field, with the first character capitalized.
+
+    * The form field's ``help_text`` is set to the ``help_text`` of the model
+      field.
+
+    * If the model field has ``choices`` set, then the form field's ``widget``
+      will be set to ``Select``, with choices coming from the model field's
+      ``choices``. The choices will normally include the blank choice which is
+      selected by default. If the field is required, this forces the user to
+      make a selection. The blank choice will not be included if the model
+      field has ``blank=False`` and an explicit ``default`` value (the
+      ``default`` value will be initially selected instead).
+
+Finally, note that you can override the form field used for a given model
+field. See `Overriding the default field types or widgets`_ below.
+
+A full example
+--------------
+
+Consider this set of models::
+
+    from django.db import models
+    from django.forms import ModelForm
+
+    TITLE_CHOICES = (
+        ('MR', 'Mr.'),
+        ('MRS', 'Mrs.'),
+        ('MS', 'Ms.'),
+    )
+
+    class Author(models.Model):
+        name = models.CharField(max_length=100)
+        title = models.CharField(max_length=3, choices=TITLE_CHOICES)
+        birth_date = models.DateField(blank=True, null=True)
+
+        def __unicode__(self):
+            return self.name
+
+    class Book(models.Model):
+        name = models.CharField(max_length=100)
+        authors = models.ManyToManyField(Author)
+
+    class AuthorForm(ModelForm):
+        class Meta:
+            model = Author
+
+    class BookForm(ModelForm):
+        class Meta:
+            model = Book
+
+With these models, the ``ModelForm`` subclasses above would be roughly
+equivalent to this (the only difference being the ``save()`` method, which
+we'll discuss in a moment.)::
+
+    class AuthorForm(forms.Form):
+        name = forms.CharField(max_length=100)
+        title = forms.CharField(max_length=3,
+                    widget=forms.Select(choices=TITLE_CHOICES))
+        birth_date = forms.DateField(required=False)
+
+    class BookForm(forms.Form):
+        name = forms.CharField(max_length=100)
+        authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
+
+The ``is_valid()`` method and ``errors``
+----------------------------------------
+
+.. versionchanged:: 1.2
+
+The first time you call ``is_valid()`` or access the ``errors`` attribute of a
+``ModelForm`` has always triggered form validation, but as of Django 1.2, it
+will also trigger :ref:`model validation <validating-objects>`. This has the
+side-effect of cleaning the model you pass to the ``ModelForm`` constructor.
+For instance, calling ``is_valid()`` on your form will convert any date fields
+on your model to actual date objects.
+
+
+The ``save()`` method
+---------------------
+
+Every form produced by ``ModelForm`` also has a ``save()``
+method. This method creates and saves a database object from the data
+bound to the form. A subclass of ``ModelForm`` can accept an existing
+model instance as the keyword argument ``instance``; if this is
+supplied, ``save()`` will update that instance. If it's not supplied,
+``save()`` will create a new instance of the specified model::
+
+    # Create a form instance from POST data.
+    >>> f = ArticleForm(request.POST)
+
+    # Save a new Article object from the form's data.
+    >>> new_article = f.save()
+
+    # Create a form to edit an existing Article.
+    >>> a = Article.objects.get(pk=1)
+    >>> f = ArticleForm(instance=a)
+    >>> f.save()
+
+    # Create a form to edit an existing Article, but use
+    # POST data to populate the form.
+    >>> a = Article.objects.get(pk=1)
+    >>> f = ArticleForm(request.POST, instance=a)
+    >>> f.save()
+
+Note that ``save()`` will raise a ``ValueError`` if the data in the form
+doesn't validate -- i.e., if form.errors evaluates to True.
+
+This ``save()`` method accepts an optional ``commit`` keyword argument, which
+accepts either ``True`` or ``False``. If you call ``save()`` with
+``commit=False``, then it will return an object that hasn't yet been saved to
+the database. In this case, it's up to you to call ``save()`` on the resulting
+model instance. This is useful if you want to do custom processing on the
+object before saving it, or if you want to use one of the specialized
+:ref:`model saving options <ref-models-force-insert>`. ``commit`` is ``True``
+by default.
+
+Another side effect of using ``commit=False`` is seen when your model has
+a many-to-many relation with another model. If your model has a many-to-many
+relation and you specify ``commit=False`` when you save a form, Django cannot
+immediately save the form data for the many-to-many relation. This is because
+it isn't possible to save many-to-many data for an instance until the instance
+exists in the database.
+
+To work around this problem, every time you save a form using ``commit=False``,
+Django adds a ``save_m2m()`` method to your ``ModelForm`` subclass. After
+you've manually saved the instance produced by the form, you can invoke
+``save_m2m()`` to save the many-to-many form data. For example::
+
+    # Create a form instance with POST data.
+    >>> f = AuthorForm(request.POST)
+
+    # Create, but don't save the new author instance.
+    >>> new_author = f.save(commit=False)
+
+    # Modify the author in some way.
+    >>> new_author.some_field = 'some_value'
+
+    # Save the new instance.
+    >>> new_author.save()
+
+    # Now, save the many-to-many data for the form.
+    >>> f.save_m2m()
+
+Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
+When you use a simple ``save()`` on a form, all data -- including
+many-to-many data -- is saved without the need for any additional method calls.
+For example::
+
+    # Create a form instance with POST data.
+    >>> a = Author()
+    >>> f = AuthorForm(request.POST, instance=a)
+
+    # Create and save the new author instance. There's no need to do anything else.
+    >>> new_author = f.save()
+
+Other than the ``save()`` and ``save_m2m()`` methods, a ``ModelForm`` works
+exactly the same way as any other ``forms`` form. For example, the
+``is_valid()`` method is used to check for validity, the ``is_multipart()``
+method is used to determine whether a form requires multipart file upload (and
+hence whether ``request.FILES`` must be passed to the form), etc. See
+:ref:`binding-uploaded-files` for more information.
+
+Using a subset of fields on the form
+------------------------------------
+
+In some cases, you may not want all the model fields to appear on the generated
+form. There are three ways of telling ``ModelForm`` to use only a subset of the
+model fields:
+
+1. Set ``editable=False`` on the model field. As a result, *any* form
+   created from the model via ``ModelForm`` will not include that
+   field.
+
+2. Use the ``fields`` attribute of the ``ModelForm``'s inner ``Meta``
+   class.  This attribute, if given, should be a list of field names
+   to include in the form.
+
+   .. versionchanged:: 1.1
+
+   The form will render the fields in the same order they are specified in the
+   ``fields`` attribute.
+
+3. Use the ``exclude`` attribute of the ``ModelForm``'s inner ``Meta``
+   class.  This attribute, if given, should be a list of field names
+   to exclude from the form.
+
+For example, if you want a form for the ``Author`` model (defined
+above) that includes only the ``name`` and ``title`` fields, you would
+specify ``fields`` or ``exclude`` like this::
+
+    class PartialAuthorForm(ModelForm):
+        class Meta:
+            model = Author
+            fields = ('name', 'title')
+
+    class PartialAuthorForm(ModelForm):
+        class Meta:
+            model = Author
+            exclude = ('birth_date',)
+
+Since the Author model has only 3 fields, 'name', 'title', and
+'birth_date', the forms above will contain exactly the same fields.
+
+.. note::
+
+    If you specify ``fields`` or ``exclude`` when creating a form with
+    ``ModelForm``, then the fields that are not in the resulting form will not
+    be set by the form's ``save()`` method. Django will prevent any attempt to
+    save an incomplete model, so if the model does not allow the missing fields
+    to be empty, and does not provide a default value for the missing fields,
+    any attempt to ``save()`` a ``ModelForm`` with missing fields will fail.
+    To avoid this failure, you must instantiate your model with initial values
+    for the missing, but required fields::
+
+        author = Author(title='Mr')
+        form = PartialAuthorForm(request.POST, instance=author)
+        form.save()
+
+    Alternatively, you can use ``save(commit=False)`` and manually set
+    any extra required fields::
+
+        form = PartialAuthorForm(request.POST)
+        author = form.save(commit=False)
+        author.title = 'Mr'
+        author.save()
+
+    See the `section on saving forms`_ for more details on using
+    ``save(commit=False)``.
+
+.. _section on saving forms: `The save() method`_
+
+Overriding the default field types or widgets
+---------------------------------------------
+
+.. versionadded:: 1.2
+ 	The ``widgets`` attribute is new in Django 1.2.
+
+The default field types, as described in the `Field types`_ table above, are
+sensible defaults. If you have a ``DateField`` in your model, chances are you'd
+want that to be represented as a ``DateField`` in your form. But
+``ModelForm`` gives you the flexibility of changing the form field type and
+widget for a given model field.
+
+To specify a custom widget for a field, use the ``widgets`` attribute of the
+inner ``Meta`` class. This should be a dictionary mapping field names to widget
+classes or instances.
+
+For example, if you want the a ``CharField`` for the ``name``
+attribute of ``Author`` to be represented by a ``<textarea>`` instead
+of its default ``<input type="text">``, you can override the field's
+widget::
+
+    from django.forms import ModelForm, Textarea
+
+    class AuthorForm(ModelForm):
+        class Meta:
+            model = Author
+            fields = ('name', 'title', 'birth_date')
+            widgets = {
+                'name': Textarea(attrs={'cols': 80, 'rows': 20}),
+            }
+
+The ``widgets`` dictionary accepts either widget instances (e.g.,
+``Textarea(...)``) or classes (e.g., ``Textarea``).
+
+If you want to further customize a field -- including its type, label, etc. --
+you can do this by declaratively specifying fields like you would in a regular
+``Form``. Declared fields will override the default ones generated by using the
+``model`` attribute.
+
+For example, if you wanted to use ``MyDateFormField`` for the ``pub_date``
+field, you could do the following::
+
+    class ArticleForm(ModelForm):
+        pub_date = MyDateFormField()
+
+        class Meta:
+            model = Article
+
+If you want to override a field's default label, then specify the ``label``
+parameter when declaring the form field::
+
+   >>> class ArticleForm(ModelForm):
+   ...     pub_date = DateField(label='Publication date')
+   ...
+   ...     class Meta:
+   ...         model = Article
+
+.. note::
+
+    If you explicitly instantiate a form field like this, Django assumes that you
+    want to completely define its behavior; therefore, default attributes (such as
+    ``max_length`` or ``required``) are not drawn from the corresponding model. If
+    you want to maintain the behavior specified in the model, you must set the
+    relevant arguments explicitly when declaring the form field.
+
+    For example, if the ``Article`` model looks like this::
+
+        class Article(models.Model):
+            headline = models.CharField(max_length=200, null=True, blank=True,
+                                        help_text="Use puns liberally")
+            content = models.TextField()
+
+    and you want to do some custom validation for ``headline``, while keeping
+    the ``blank`` and ``help_text`` values as specified, you might define
+    ``ArticleForm`` like this::
+
+        class ArticleForm(ModelForm):
+            headline = MyFormField(max_length=200, required=False,
+                                   help_text="Use puns liberally")
+
+            class Meta:
+                model = Article
+
+    See the :doc:`form field documentation </ref/forms/fields>` for more information
+    on fields and their arguments.
+
+Changing the order of fields
+----------------------------
+
+.. versionadded:: 1.1
+
+By default, a ``ModelForm`` will render fields in the same order that they are
+defined on the model, with ``ManyToManyField`` instances appearing last. If
+you want to change the order in which fields are rendered, you can use the
+``fields`` attribute on the ``Meta`` class.
+
+The ``fields`` attribute defines the subset of model fields that will be
+rendered, and the order in which they will be rendered. For example given this
+model::
+
+    class Book(models.Model):
+        author = models.ForeignKey(Author)
+        title = models.CharField(max_length=100)
+
+the ``author`` field would be rendered first. If we wanted the title field
+to be rendered first, we could specify the following ``ModelForm``::
+
+    >>> class BookForm(ModelForm):
+    ...     class Meta:
+    ...         model = Book
+    ...         fields = ('title', 'author')
+
+.. _overriding-modelform-clean-method:
+
+Overriding the clean() method
+-----------------------------
+
+You can override the ``clean()`` method on a model form to provide additional
+validation in the same way you can on a normal form.
+
+In this regard, model forms have two specific characteristics when compared to
+forms:
+
+By default the ``clean()`` method validates the uniqueness of fields that are
+marked as ``unique``, ``unique_together`` or ``unique_for_date|month|year`` on
+the model.  Therefore, if you would like to override the ``clean()`` method and
+maintain the default validation, you must call the parent class's ``clean()``
+method.
+
+Also, a model form instance bound to a model object will contain a
+``self.instance`` attribute that gives model form methods access to that
+specific model instance.
+
+Form inheritance
+----------------
+
+As with basic forms, you can extend and reuse ``ModelForms`` by inheriting
+them. This is useful if you need to declare extra fields or extra methods on a
+parent class for use in a number of forms derived from models. For example,
+using the previous ``ArticleForm`` class::
+
+    >>> class EnhancedArticleForm(ArticleForm):
+    ...     def clean_pub_date(self):
+    ...         ...
+
+This creates a form that behaves identically to ``ArticleForm``, except there's
+some extra validation and cleaning for the ``pub_date`` field.
+
+You can also subclass the parent's ``Meta`` inner class if you want to change
+the ``Meta.fields`` or ``Meta.excludes`` lists::
+
+    >>> class RestrictedArticleForm(EnhancedArticleForm):
+    ...     class Meta(ArticleForm.Meta):
+    ...         exclude = ('body',)
+
+This adds the extra method from the ``EnhancedArticleForm`` and modifies
+the original ``ArticleForm.Meta`` to remove one field.
+
+There are a couple of things to note, however.
+
+ * Normal Python name resolution rules apply. If you have multiple base
+   classes that declare a ``Meta`` inner class, only the first one will be
+   used. This means the child's ``Meta``, if it exists, otherwise the
+   ``Meta`` of the first parent, etc.
+
+ * For technical reasons, a subclass cannot inherit from both a ``ModelForm``
+   and a ``Form`` simultaneously.
+
+Chances are these notes won't affect you unless you're trying to do something
+tricky with subclassing.
+
+Interaction with model validation
+---------------------------------
+
+As part of its validation process, ``ModelForm`` will call the ``clean()``
+method of each field on your model that has a corresponding field on your form.
+If you have excluded any model fields, validation will not be run on those
+fields. See the :doc:`form validation </ref/forms/validation>` documentation
+for more on how field cleaning and validation work. Also, your model's
+``clean()`` method will be called before any uniqueness checks are made. See
+:ref:`Validating objects <validating-objects>` for more information on the
+model's ``clean()`` hook.
+
+.. _model-formsets:
+
+Model formsets
+==============
+
+Like :doc:`regular formsets </topics/forms/formsets>`, Django provides a couple
+of enhanced formset classes that make it easy to work with Django models. Let's
+reuse the ``Author`` model from above::
+
+    >>> from django.forms.models import modelformset_factory
+    >>> AuthorFormSet = modelformset_factory(Author)
+
+This will create a formset that is capable of working with the data associated
+with the ``Author`` model. It works just like a regular formset::
+
+    >>> formset = AuthorFormSet()
+    >>> print formset
+    <input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="0" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" id="id_form-MAX_NUM_FORMS" />
+    <tr><th><label for="id_form-0-name">Name:</label></th><td><input id="id_form-0-name" type="text" name="form-0-name" maxlength="100" /></td></tr>
+    <tr><th><label for="id_form-0-title">Title:</label></th><td><select name="form-0-title" id="id_form-0-title">
+    <option value="" selected="selected">---------</option>
+    <option value="MR">Mr.</option>
+    <option value="MRS">Mrs.</option>
+    <option value="MS">Ms.</option>
+    </select></td></tr>
+    <tr><th><label for="id_form-0-birth_date">Birth date:</label></th><td><input type="text" name="form-0-birth_date" id="id_form-0-birth_date" /><input type="hidden" name="form-0-id" id="id_form-0-id" /></td></tr>
+
+.. note::
+    ``modelformset_factory`` uses ``formset_factory`` to generate formsets.
+    This means that a model formset is just an extension of a basic formset
+    that knows how to interact with a particular model.
+
+Changing the queryset
+---------------------
+
+By default, when you create a formset from a model, the formset will use a
+queryset that includes all objects in the model (e.g.,
+``Author.objects.all()``). You can override this behavior by using the
+``queryset`` argument::
+
+    >>> formset = AuthorFormSet(queryset=Author.objects.filter(name__startswith='O'))
+
+Alternatively, you can create a subclass that sets ``self.queryset`` in
+``__init__``::
+
+    from django.forms.models import BaseModelFormSet
+
+    class BaseAuthorFormSet(BaseModelFormSet):
+        def __init__(self, *args, **kwargs):
+            super(BaseAuthorFormSet, self).__init__(*args, **kwargs)
+            self.queryset = Author.objects.filter(name__startswith='O')
+
+Then, pass your ``BaseAuthorFormSet`` class to the factory function::
+
+    >>> AuthorFormSet = modelformset_factory(Author, formset=BaseAuthorFormSet)
+
+If you want to return a formset that doesn't include *any* pre-existing
+instances of the model, you can specify an empty QuerySet::
+
+   >>> AuthorFormSet(queryset=Author.objects.none())
+
+
+Controlling which fields are used with ``fields`` and ``exclude``
+-----------------------------------------------------------------
+
+By default, a model formset uses all fields in the model that are not marked
+with ``editable=False``. However, this can be overridden at the formset level::
+
+    >>> AuthorFormSet = modelformset_factory(Author, fields=('name', 'title'))
+
+Using ``fields`` restricts the formset to use only the given fields.
+Alternatively, you can take an "opt-out" approach, specifying which fields to
+exclude::
+
+    >>> AuthorFormSet = modelformset_factory(Author, exclude=('birth_date',))
+
+.. _saving-objects-in-the-formset:
+
+Saving objects in the formset
+-----------------------------
+
+As with a ``ModelForm``, you can save the data as a model object. This is done
+with the formset's ``save()`` method::
+
+    # Create a formset instance with POST data.
+    >>> formset = AuthorFormSet(request.POST)
+
+    # Assuming all is valid, save the data.
+    >>> instances = formset.save()
+
+The ``save()`` method returns the instances that have been saved to the
+database. If a given instance's data didn't change in the bound data, the
+instance won't be saved to the database and won't be included in the return
+value (``instances``, in the above example).
+
+Pass ``commit=False`` to return the unsaved model instances::
+
+    # don't save to the database
+    >>> instances = formset.save(commit=False)
+    >>> for instance in instances:
+    ...     # do something with instance
+    ...     instance.save()
+
+This gives you the ability to attach data to the instances before saving them
+to the database. If your formset contains a ``ManyToManyField``, you'll also
+need to call ``formset.save_m2m()`` to ensure the many-to-many relationships
+are saved properly.
+
+.. _model-formsets-max-num:
+
+Limiting the number of editable objects
+---------------------------------------
+
+.. versionchanged:: 1.2
+
+As with regular formsets, you can use the ``max_num`` and ``extra`` parameters
+to ``modelformset_factory`` to limit the number of extra forms displayed.
+
+``max_num`` does not prevent existing objects from being displayed::
+
+    >>> Author.objects.order_by('name')
+    [<Author: Charles Baudelaire>, <Author: Paul Verlaine>, <Author: Walt Whitman>]
+
+    >>> AuthorFormSet = modelformset_factory(Author, max_num=1)
+    >>> formset = AuthorFormSet(queryset=Author.objects.order_by('name'))
+    >>> [x.name for x in formset.get_queryset()]
+    [u'Charles Baudelaire', u'Paul Verlaine', u'Walt Whitman']
+
+If the value of ``max_num`` is greater than the number of existing related
+objects, up to ``extra`` additional blank forms will be added to the formset,
+so long as the total number of forms does not exceed ``max_num``::
+
+    >>> AuthorFormSet = modelformset_factory(Author, max_num=4, extra=2)
+    >>> formset = AuthorFormSet(queryset=Author.objects.order_by('name'))
+    >>> for form in formset.forms:
+    ...     print form.as_table()
+    <tr><th><label for="id_form-0-name">Name:</label></th><td><input id="id_form-0-name" type="text" name="form-0-name" value="Charles Baudelaire" maxlength="100" /><input type="hidden" name="form-0-id" value="1" id="id_form-0-id" /></td></tr>
+    <tr><th><label for="id_form-1-name">Name:</label></th><td><input id="id_form-1-name" type="text" name="form-1-name" value="Paul Verlaine" maxlength="100" /><input type="hidden" name="form-1-id" value="3" id="id_form-1-id" /></td></tr>
+    <tr><th><label for="id_form-2-name">Name:</label></th><td><input id="id_form-2-name" type="text" name="form-2-name" value="Walt Whitman" maxlength="100" /><input type="hidden" name="form-2-id" value="2" id="id_form-2-id" /></td></tr>
+    <tr><th><label for="id_form-3-name">Name:</label></th><td><input id="id_form-3-name" type="text" name="form-3-name" maxlength="100" /><input type="hidden" name="form-3-id" id="id_form-3-id" /></td></tr>
+
+.. versionchanged:: 1.2
+
+A ``max_num`` value of ``None`` (the default) puts no limit on the number of
+forms displayed.
+
+Using a model formset in a view
+-------------------------------
+
+Model formsets are very similar to formsets. Let's say we want to present a
+formset to edit ``Author`` model instances::
+
+    def manage_authors(request):
+        AuthorFormSet = modelformset_factory(Author)
+        if request.method == 'POST':
+            formset = AuthorFormSet(request.POST, request.FILES)
+            if formset.is_valid():
+                formset.save()
+                # do something.
+        else:
+            formset = AuthorFormSet()
+        return render_to_response("manage_authors.html", {
+            "formset": formset,
+        })
+
+As you can see, the view logic of a model formset isn't drastically different
+than that of a "normal" formset. The only difference is that we call
+``formset.save()`` to save the data into the database. (This was described
+above, in :ref:`saving-objects-in-the-formset`.)
+
+Overiding ``clean()`` on a ``model_formset``
+--------------------------------------------
+
+Just like with ``ModelForms``, by default the ``clean()`` method of a
+``model_formset`` will validate that none of the items in the formset violate
+the unique constraints on your model (either ``unique``, ``unique_together`` or
+``unique_for_date|month|year``).  If you want to overide the ``clean()`` method
+on a ``model_formset`` and maintain this validation, you must call the parent
+class's ``clean`` method::
+
+    class MyModelFormSet(BaseModelFormSet):
+        def clean(self):
+            super(MyModelFormSet, self).clean()
+            # example custom validation across forms in the formset:
+            for form in self.forms:
+                # your custom formset validation
+
+Using a custom queryset
+-----------------------
+
+As stated earlier, you can override the default queryset used by the model
+formset::
+
+    def manage_authors(request):
+        AuthorFormSet = modelformset_factory(Author)
+        if request.method == "POST":
+            formset = AuthorFormSet(request.POST, request.FILES,
+                                    queryset=Author.objects.filter(name__startswith='O'))
+            if formset.is_valid():
+                formset.save()
+                # Do something.
+        else:
+            formset = AuthorFormSet(queryset=Author.objects.filter(name__startswith='O'))
+        return render_to_response("manage_authors.html", {
+            "formset": formset,
+        })
+
+Note that we pass the ``queryset`` argument in both the ``POST`` and ``GET``
+cases in this example.
+
+Using the formset in the template
+---------------------------------
+
+.. highlight:: html+django
+
+There are three ways to render a formset in a Django template.
+
+First, you can let the formset do most of the work::
+
+    <form method="post" action="">
+        {{ formset }}
+    </form>
+
+Second, you can manually render the formset, but let the form deal with
+itself::
+
+    <form method="post" action="">
+        {{ formset.management_form }}
+        {% for form in formset.forms %}
+            {{ form }}
+        {% endfor %}
+    </form>
+
+When you manually render the forms yourself, be sure to render the management
+form as shown above. See the :ref:`management form documentation
+<understanding-the-managementform>`.
+
+Third, you can manually render each field::
+
+    <form method="post" action="">
+        {{ formset.management_form }}
+        {% for form in formset.forms %}
+            {% for field in form %}
+                {{ field.label_tag }}: {{ field }}
+            {% endfor %}
+        {% endfor %}
+    </form>
+
+If you opt to use this third method and you don't iterate over the fields with
+a ``{% for %}`` loop, you'll need to render the primary key field. For example,
+if you were rendering the ``name`` and ``age`` fields of a model::
+
+    <form method="post" action="">
+        {{ formset.management_form }}
+        {% for form in formset.forms %}
+            {{ form.id }}
+            <ul>
+                <li>{{ form.name }}</li>
+                <li>{{ form.age }}</li>
+            </ul>
+        {% endfor %}
+    </form>
+
+Notice how we need to explicitly render ``{{ form.id }}``. This ensures that
+the model formset, in the ``POST`` case, will work correctly. (This example
+assumes a primary key named ``id``. If you've explicitly defined your own
+primary key that isn't called ``id``, make sure it gets rendered.)
+
+.. highlight:: python
+
+Inline formsets
+===============
+
+Inline formsets is a small abstraction layer on top of model formsets. These
+simplify the case of working with related objects via a foreign key. Suppose
+you have these two models::
+
+    class Author(models.Model):
+        name = models.CharField(max_length=100)
+
+    class Book(models.Model):
+        author = models.ForeignKey(Author)
+        title = models.CharField(max_length=100)
+
+If you want to create a formset that allows you to edit books belonging to
+a particular author, you could do this::
+
+    >>> from django.forms.models import inlineformset_factory
+    >>> BookFormSet = inlineformset_factory(Author, Book)
+    >>> author = Author.objects.get(name=u'Mike Royko')
+    >>> formset = BookFormSet(instance=author)
+
+.. note::
+    ``inlineformset_factory`` uses ``modelformset_factory`` and marks
+    ``can_delete=True``.
+
+More than one foreign key to the same model
+-------------------------------------------
+
+If your model contains more than one foreign key to the same model, you'll
+need to resolve the ambiguity manually using ``fk_name``. For example, consider
+the following model::
+
+    class Friendship(models.Model):
+        from_friend = models.ForeignKey(Friend)
+        to_friend = models.ForeignKey(Friend)
+        length_in_months = models.IntegerField()
+
+To resolve this, you can use ``fk_name`` to ``inlineformset_factory``::
+
+    >>> FriendshipFormSet = inlineformset_factory(Friend, Friendship, fk_name="from_friend")
+
+Using an inline formset in a view
+---------------------------------
+
+You may want to provide a view that allows a user to edit the related objects
+of a model. Here's how you can do that::
+
+    def manage_books(request, author_id):
+        author = Author.objects.get(pk=author_id)
+        BookInlineFormSet = inlineformset_factory(Author, Book)
+        if request.method == "POST":
+            formset = BookInlineFormSet(request.POST, request.FILES, instance=author)
+            if formset.is_valid():
+                formset.save()
+                # Do something.
+        else:
+            formset = BookInlineFormSet(instance=author)
+        return render_to_response("manage_books.html", {
+            "formset": formset,
+        })
+
+Notice how we pass ``instance`` in both the ``POST`` and ``GET`` cases.