Fixed #13524 -- Added backwards compatibility and feature notes regarding admin inlines and formsets. Thanks to Ramiro Morales and Gabriel Hurley.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13241 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2010-05-12 11:56:42 +00:00
parent b8ed827952
commit d0d3e6792d
6 changed files with 114 additions and 17 deletions

View File

@ -1053,6 +1053,8 @@ The value for ``form`` defaults to ``ModelForm``. This is what is
passed through to ``inlineformset_factory`` when creating the formset for this passed through to ``inlineformset_factory`` when creating the formset for this
inline. inline.
.. _ref-contrib-admin-inline-extra:
``extra`` ``extra``
~~~~~~~~~ ~~~~~~~~~
@ -1062,8 +1064,15 @@ to the initial forms. See the
.. versionadded:: 1.2 .. versionadded:: 1.2
Extra forms for inlines will be hidden and replaced with a link to dynamically For users with JavaScript-enabled browsers, an "Add another" link is
add any number of new inlines for users with Javascript enabled. provided to enable any number of additional inlines to be added in
addition to those provided as a result of the ``extra`` argument.
The dynamic link will not appear if the number of currently displayed
forms exceeds ``max_num``, or if the user does not have JavaScript
enabled.
.. _ref-contrib-admin-inline-max-num:
``max_num`` ``max_num``
~~~~~~~~~~~ ~~~~~~~~~~~

View File

@ -351,6 +351,39 @@ people this shouldn't have been a problem because ``bool`` is a subclass of
only time this should ever be an issue is if you were expecting printing the only time this should ever be an issue is if you were expecting printing the
``repr`` of a ``BooleanField`` to print ``1`` or ``0``. ``repr`` of a ``BooleanField`` to print ``1`` or ``0``.
Changes to the interpretation of``max_num`` in FormSets
-------------------------------------------------------
As part of enhancements made to the handling of FormSets, the default
value and interpretation of the ``max_num`` parameter to the
:ref:`django.forms.formsets.formset_factory() <formsets-max-num>` and
:ref:`django.forms.models.modelformset_factory()
<model-formsets-max-num>` functions has changed slightly. This
change also affects the way the ``max_num`` argument is :ref:`used for
inline admin objects <ref-contrib-admin-inline-max-num>`
Previously, the default value for ``max_num`` was ``0`` (zero).
FormSets then used the boolean value of ``max_num`` to determine if a
limit was to be imposed on the number of generated forms. The default
value of ``0`` meant that there was no default limit on the number of
forms in a FormSet.
Starting with 1.2, the default value for ``max_num`` has been changed
to ``None``, and FormSets will differentiate between a value of
``None`` and a value of ``0``. A value of ``None`` indicates that no
limit on the number of forms is to be imposed; a value of ``0``
indicates that a maximum of 0 forms should be imposed. This doesn't
necessarily mean that no forms will be displayed -- see the
:ref:`ModelFormSet documentation <model-formsets-max-num>` for more
details.
If you were manually specifying a value of ``0`` for ``max_num``, you
will need to update your FormSet and/or admin definitions.
.. seealso::
:ref:`1.2-js-assisted-inlines`
.. _deprecated-features-1.2: .. _deprecated-features-1.2:
Features deprecated in 1.2 Features deprecated in 1.2
@ -678,6 +711,11 @@ for your spatial database use the methods provided by the spatial backend::
sr_qs = SpatialRefSys.objects.using('my_spatialite').filter(...) sr_qs = SpatialRefSys.objects.using('my_spatialite').filter(...)
gc_qs = GeometryColumns.objects.using('my_postgis').filter(...) gc_qs = GeometryColumns.objects.using('my_postgis').filter(...)
Language code ``no``
--------------------
The currently used language code for Norwegian Bokmål ``no`` is being
replaced by the more common language code ``nb``.
What's new in Django 1.2 What's new in Django 1.2
======================== ========================
@ -923,9 +961,12 @@ Finally, :ref:`GeoDjango's documentation <ref-contrib-gis>` is now
included with Django's and is no longer included with Django's and is no longer
hosted separately at `geodjango.org <http://geodjango.org/>`_. hosted separately at `geodjango.org <http://geodjango.org/>`_.
Deprecation of old language code ``no`` .. _1.2-js-assisted-inlines:
---------------------------------------
The currently used language code for Norwegian Bokmål ``no`` is being JavaScript-assisted handling of inline related objects in the admin
replaced by the more common language code ``nb``, which should be updated -------------------------------------------------------------------
by translators from now on.
If a user has JavaScript enabled in their browser, the interface for
inline objects in the admin now allows inline objects to be
dynamically added and removed. Users without JavaScript-enabled
browsers will see no change in the behavior of inline objects.

View File

@ -68,6 +68,8 @@ list of dictionaries as the initial data.
:ref:`Creating formsets from models with model formsets <model-formsets>`. :ref:`Creating formsets from models with model formsets <model-formsets>`.
.. _formsets-max-num:
Limiting the maximum number of forms Limiting the maximum number of forms
------------------------------------ ------------------------------------
@ -83,7 +85,7 @@ limit the maximum number of empty forms the formset will display::
.. versionchanged:: 1.2 .. versionchanged:: 1.2
If the value of ``max_num`` is geater than the number of existing related If the value of ``max_num`` is greater than the number of existing
objects, up to ``extra`` additional blank forms will be added to the formset, 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``. so long as the total number of forms does not exceed ``max_num``.
@ -91,11 +93,6 @@ A ``max_num`` value of ``None`` (the default) puts no limit on the number of
forms displayed. Please note that the default value of ``max_num`` was changed forms displayed. Please note that the default value of ``max_num`` was changed
from ``0`` to ``None`` in version 1.2 to allow ``0`` as a valid value. from ``0`` to ``None`` in version 1.2 to allow ``0`` as a valid value.
.. versionadded:: 1.2
The dynamic "Add Another" link in the Django admin will not appear if
``max_num`` is less than the number of currently displayed forms.
Formset validation Formset validation
------------------ ------------------

View File

@ -661,8 +661,8 @@ Limiting the number of editable objects
.. versionchanged:: 1.2 .. versionchanged:: 1.2
As with regular formsets, you can use the ``max_num`` parameter to As with regular formsets, you can use the ``max_num`` and ``extra`` parameters
``modelformset_factory`` to limit the number of extra forms displayed. to ``modelformset_factory`` to limit the number of extra forms displayed.
``max_num`` does not prevent existing objects from being displayed:: ``max_num`` does not prevent existing objects from being displayed::

View File

@ -368,16 +368,22 @@ the creation of new inlines beyond max_num.
>>> AuthorFormSet = modelformset_factory(Author, max_num=None, extra=3) >>> AuthorFormSet = modelformset_factory(Author, max_num=None, extra=3)
>>> formset = AuthorFormSet(queryset=qs) >>> formset = AuthorFormSet(queryset=qs)
>>> len(formset.forms)
6
>>> len(formset.extra_forms) >>> len(formset.extra_forms)
3 3
>>> AuthorFormSet = modelformset_factory(Author, max_num=4, extra=3) >>> AuthorFormSet = modelformset_factory(Author, max_num=4, extra=3)
>>> formset = AuthorFormSet(queryset=qs) >>> formset = AuthorFormSet(queryset=qs)
>>> len(formset.forms)
4
>>> len(formset.extra_forms) >>> len(formset.extra_forms)
1 1
>>> AuthorFormSet = modelformset_factory(Author, max_num=0, extra=3) >>> AuthorFormSet = modelformset_factory(Author, max_num=0, extra=3)
>>> formset = AuthorFormSet(queryset=qs) >>> formset = AuthorFormSet(queryset=qs)
>>> len(formset.forms)
3
>>> len(formset.extra_forms) >>> len(formset.extra_forms)
0 0

View File

@ -599,6 +599,24 @@ True
# Base case for max_num. # Base case for max_num.
# When not passed, max_num will take its default value of None, i.e. unlimited
# number of forms, only controlled by the value of the extra parameter.
>>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=3)
>>> formset = LimitedFavoriteDrinkFormSet()
>>> for form in formset.forms:
... print form
<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" id="id_form-0-name" /></td></tr>
<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr>
<tr><th><label for="id_form-2-name">Name:</label></th><td><input type="text" name="form-2-name" id="id_form-2-name" /></td></tr>
# If max_num is 0 then no form is rendered at all.
>>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=3, max_num=0)
>>> formset = LimitedFavoriteDrinkFormSet()
>>> for form in formset.forms:
... print form
>>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=5, max_num=2) >>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=5, max_num=2)
>>> formset = LimitedFavoriteDrinkFormSet() >>> formset = LimitedFavoriteDrinkFormSet()
>>> for form in formset.forms: >>> for form in formset.forms:
@ -606,7 +624,7 @@ True
<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" id="id_form-0-name" /></td></tr> <tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" id="id_form-0-name" /></td></tr>
<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr> <tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr>
# Ensure the that max_num has no affect when extra is less than max_forms. # Ensure that max_num has no effect when extra is less than max_num.
>>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=2) >>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=2)
>>> formset = LimitedFavoriteDrinkFormSet() >>> formset = LimitedFavoriteDrinkFormSet()
@ -616,6 +634,32 @@ True
# max_num with initial data # max_num with initial data
# When not passed, max_num will take its default value of None, i.e. unlimited
# number of forms, only controlled by the values of the initial and extra
# parameters.
>>> initial = [
... {'name': 'Fernet and Coke'},
... ]
>>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1)
>>> formset = LimitedFavoriteDrinkFormSet(initial=initial)
>>> for form in formset.forms:
... print form
<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" value="Fernet and Coke" id="id_form-0-name" /></td></tr>
<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr>
# If max_num is 0 then no form is rendered at all, even if extra and initial
# are specified.
>>> initial = [
... {'name': 'Fernet and Coke'},
... {'name': 'Bloody Mary'},
... ]
>>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=0)
>>> formset = LimitedFavoriteDrinkFormSet(initial=initial)
>>> for form in formset.forms:
... print form
# More initial forms than max_num will result in only the first max_num of # More initial forms than max_num will result in only the first max_num of
# them to be displayed with no extra forms. # them to be displayed with no extra forms.