diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt
index bfc066d251..e2804cb9f5 100644
--- a/docs/topics/forms/modelforms.txt
+++ b/docs/topics/forms/modelforms.txt
@@ -671,7 +671,7 @@ There are a couple of things to note, however.
You can only use this technique to opt out from a field defined declaratively
by a parent class; it won't prevent the ``ModelForm`` metaclass from generating
a default field. To opt-out from default fields, see
- :ref:`controlling-fields-with-fields-and-exclude`.
+ :ref:`modelforms-selecting-fields`.
.. _modelforms-factory:
@@ -716,7 +716,19 @@ reuse the ``Author`` model from above::
>>> from django.forms.models import modelformset_factory
>>> from myapp.models import Author
- >>> AuthorFormSet = modelformset_factory(Author)
+ >>> 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',))
+
+.. versionchanged:: 1.8
+
+ In older versions, omitting both ``fields`` and ``exclude`` resulted in
+ a formset with all the model's fields. Doing this now raises an
+ :exc:`~django.core.exceptions.ImproperlyConfigured` exception.
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::
@@ -730,8 +742,7 @@ with the ``Author`` model. It works just like a regular formset::
-
-
+
.. note::
@@ -763,7 +774,8 @@ Alternatively, you can create a subclass that sets ``self.queryset`` in
Then, pass your ``BaseAuthorFormSet`` class to the factory function::
- >>> AuthorFormSet = modelformset_factory(Author, formset=BaseAuthorFormSet)
+ >>> AuthorFormSet = modelformset_factory(
+ ... Author, fields=('name', 'title'), 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::
@@ -795,22 +807,6 @@ It is not always necessary to define a custom model form. The
``modelformset_factory`` function has several arguments which are
passed through to ``modelform_factory``, which are described below.
-.. _controlling-fields-with-fields-and-exclude:
-
-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',))
-
Specifying widgets to use in the form with ``widgets``
------------------------------------------------------
@@ -820,7 +816,8 @@ works the same way as the ``widgets`` dictionary on the inner ``Meta``
class of a ``ModelForm`` works::
>>> AuthorFormSet = modelformset_factory(
- ... Author, widgets={'name': Textarea(attrs={'cols': 80, 'rows': 20})
+ ... Author, fields=('name', 'title'),
+ ... widgets={'name': Textarea(attrs={'cols': 80, 'rows': 20})})
Enabling localization for fields with ``localized_fields``
----------------------------------------------------------
@@ -829,7 +826,8 @@ Using the ``localized_fields`` parameter, you can enable localization for
fields in the form.
>>> AuthorFormSet = modelformset_factory(
- ... Author, localized_fields=('value',))
+ ... Author, fields=('name', 'title', 'birth_date'),
+ ... localized_fields=('birth_date',))
If ``localized_fields`` is set to the special value ``'__all__'``, all fields
will be localized.
@@ -906,7 +904,7 @@ extra forms displayed.
>>> Author.objects.order_by('name')
[, , ]
- >>> AuthorFormSet = modelformset_factory(Author, max_num=1)
+ >>> AuthorFormSet = modelformset_factory(Author, fields=('name',), max_num=1)
>>> formset = AuthorFormSet(queryset=Author.objects.order_by('name'))
>>> [x.name for x in formset.get_queryset()]
['Charles Baudelaire', 'Paul Verlaine', 'Walt Whitman']
@@ -915,7 +913,7 @@ 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)
+ >>> AuthorFormSet = modelformset_factory(Author, fields=('name',), max_num=4, extra=2)
>>> formset = AuthorFormSet(queryset=Author.objects.order_by('name'))
>>> for form in formset:
... print(form.as_table())
@@ -938,7 +936,7 @@ formset to edit ``Author`` model instances::
from myapp.models import Author
def manage_authors(request):
- AuthorFormSet = modelformset_factory(Author)
+ AuthorFormSet = modelformset_factory(Author, fields=('name', 'title'))
if request.method == 'POST':
formset = AuthorFormSet(request.POST, request.FILES)
if formset.is_valid():
@@ -1006,7 +1004,7 @@ formset::
from myapp.models import Author
def manage_authors(request):
- AuthorFormSet = modelformset_factory(Author)
+ AuthorFormSet = modelformset_factory(Author, fields=('name', 'title'))
if request.method == "POST":
formset = AuthorFormSet(request.POST, request.FILES,
queryset=Author.objects.filter(name__startswith='O'))
@@ -1106,7 +1104,7 @@ 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)
+ >>> BookFormSet = inlineformset_factory(Author, Book, fields=('title',))
>>> author = Author.objects.get(name='Mike Royko')
>>> formset = BookFormSet(instance=author)
@@ -1145,7 +1143,8 @@ Then when you create your inline formset, pass in the optional argument
``formset``::
>>> from django.forms.models import inlineformset_factory
- >>> BookFormSet = inlineformset_factory(Author, Book, formset=CustomInlineFormSet)
+ >>> BookFormSet = inlineformset_factory(Author, Book, fields=('title',),
+ ... formset=CustomInlineFormSet)
>>> author = Author.objects.get(name='Mike Royko')
>>> formset = BookFormSet(instance=author)
@@ -1157,14 +1156,15 @@ 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)
+ from_friend = models.ForeignKey(Friend, related_name='from_friends')
+ to_friend = models.ForeignKey(Friend, related_name='friends')
length_in_months = models.IntegerField()
To resolve this, you can use ``fk_name`` to
:func:`~django.forms.models.inlineformset_factory`::
- >>> FriendshipFormSet = inlineformset_factory(Friend, Friendship, fk_name="from_friend")
+ >>> FriendshipFormSet = inlineformset_factory(Friend, Friendship, fk_name='from_friend',
+ ... fields=('to_friend', 'length_in_months'))
Using an inline formset in a view
---------------------------------
@@ -1174,7 +1174,7 @@ 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)
+ BookInlineFormSet = inlineformset_factory(Author, Book, fields=('title',))
if request.method == "POST":
formset = BookInlineFormSet(request.POST, request.FILES, instance=author)
if formset.is_valid():