Author: brosner
Date: 2008-12-08 18:31:17 -0600 (Mon, 08 Dec 2008)
New Revision: 9614

Modified:
   django/trunk/docs/topics/forms/modelforms.txt
Log:
Improved the model formset and inline formset documentation to be more explicit 
and handle some cases that were never addressed before.

Modified: django/trunk/docs/topics/forms/modelforms.txt
===================================================================
--- django/trunk/docs/topics/forms/modelforms.txt       2008-12-08 18:37:08 UTC 
(rev 9613)
+++ django/trunk/docs/topics/forms/modelforms.txt       2008-12-09 00:31:17 UTC 
(rev 9614)
@@ -530,7 +530,7 @@
                 # do something.
         else:
             formset = AuthorFormSet()
-        render_to_response("manage_authors.html", {
+        return render_to_response("manage_authors.html", {
             "formset": formset,
         })
 
@@ -539,13 +539,92 @@
 data into the database. This is described above in
 :ref:`saving-objects-in-the-formset`.
 
-Using ``inlineformset_factory``
--------------------------------
+Using a custom queryset
+~~~~~~~~~~~~~~~~~~~~~~~
 
-The ``inlineformset_factory`` is a helper to a common usage pattern of working
-with related objects through a foreign key. It takes all the same options as
-a ``modelformset_factory``. Suppose you have these two models::
+As stated earlier you can override the default queryset the model formset
+uses::
 
+    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,
+        })
+
+What is critical to point out here is that you must pass the queryset in both
+the ``POST`` and ``GET`` cases shown above.
+
+Using the formset in the template
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There are three ways you might want to render the formset in your template.
+You can let the formset do most of the work::
+
+    <form method="POST" action="">
+        {{ formset }}
+    </form>
+
+You can manually render the formset, but let the form deal with it self::
+
+    <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. Also see the :ref:`management form documentation 
<understanding-the-managementform>`.
+
+Or you can just do it all yourself::
+
+    <form method="POST" action="">
+        {{ formset.management_form }}
+        {% for form in formset.formset %}
+            {% for fields in form %}
+                {{ field }}
+            {% endfor %}
+        {% endfor %}
+    </form>
+
+It is critical to note that if you opt to do most of the work yourself and you
+don't go with a field ``{% for %}`` loop of the form, as shown in the last
+example, you need to render to the primary key field. For example if you were
+to render just the ``name`` and ``age`` fields of a model::
+
+    <form method="POST" action="">
+        {{ formset.management_form }}
+        {% for form in formset.formset %}
+            {{ form.id }}
+            <ul>
+                <li>{{ form.name }}</li>
+                <li>{{ form.age }}</li>
+            </ul>
+        {% endfor %}
+    </form>
+
+Notice how we need to explicitly render ``{{ form.id }}``. This will ensure
+the model formset, in the ``POST`` case, will work correctly. The above
+example is assuming a primary key named ``id`` which is the name of the
+implicit primary key Django creates for you when one isn't given. If you have
+explicitly defined your own primary key field just make sure it gets rendered
+(it is likely to be a visible field anyway).
+
+Inline Formsets
+===============
+
+Inline formsets is a small abstraction layer on top of model formsets. It
+simplifies 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)
     
@@ -554,7 +633,7 @@
         title = models.CharField(max_length=100)
 
 If you want to create a formset that allows you to edit books belonging to
-some author you would do::
+some author you might do::
 
     >>> from django.forms.models import inlineformset_factory
     >>> BookFormSet = inlineformset_factory(Author, Book)
@@ -566,7 +645,7 @@
     ``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 will
 need to resolve the ambiguity manually using ``fk_name``. Given the following
@@ -580,3 +659,27 @@
 To resolve this you can simply use ``fk_name`` to ``inlineformset_factory``::
 
     >>> FrienshipFormSet = 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 some model. Here is how you might construct this view::
+
+    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 the instance in both the ``POST`` and ``GET`` cases. This
+is required similiar to model formsets since the ``instance`` is simply used
+to create the queryset for the model formset that lives underneath.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to