[1.8.x] Fixed #24255 -- Specifed 'fields' parameter in modelformset_factory / inlineformset_factory examples.

Backport of 8d64aae883 from master
This commit is contained in:
Matt Westcott 2015-01-30 23:14:46 +00:00 committed by Tim Graham
parent 3cd8f51f21
commit ef90ca5f42
1 changed files with 33 additions and 33 deletions

View File

@ -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::
<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>
</select><input type="hidden" name="form-0-id" id="id_form-0-id" /></td></tr>
.. 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')
[<Author: Charles Baudelaire>, <Author: Paul Verlaine>, <Author: Walt Whitman>]
>>> 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():