Skip to content

Commit

Permalink
Fixed #13524 -- Added backwards compatibility and feature notes regar…
Browse files Browse the repository at this point in the history
…ding 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
  • Loading branch information
freakboy3742 committed May 12, 2010
1 parent b8ed827 commit d0d3e67
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 17 deletions.
13 changes: 11 additions & 2 deletions docs/ref/contrib/admin/index.txt
Expand Up @@ -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
inline.

.. _ref-contrib-admin-inline-extra:

``extra``
~~~~~~~~~

Expand All @@ -1062,8 +1064,15 @@ to the initial forms. See the

.. versionadded:: 1.2

Extra forms for inlines will be hidden and replaced with a link to dynamically
add any number of new inlines for users with Javascript enabled.
For users with JavaScript-enabled browsers, an "Add another" link is
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``
~~~~~~~~~~~
Expand Down
53 changes: 47 additions & 6 deletions docs/releases/1.2.txt
Expand Up @@ -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
``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:

Features deprecated in 1.2
Expand Down Expand Up @@ -611,7 +644,7 @@ were affected by these changes.
``SpatialBackend``
^^^^^^^^^^^^^^^^^^

Prior to the creation of the separate spatial backends, the
Prior to the creation of the separate spatial backends, the
``django.contrib.gis.db.backend.SpatialBackend`` object was
provided as an abstraction to introspect on the capabilities of
the spatial database. All of the attributes and routines provided by
Expand Down Expand Up @@ -678,6 +711,11 @@ for your spatial database use the methods provided by the spatial backend::
sr_qs = SpatialRefSys.objects.using('my_spatialite').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
========================
Expand Down Expand Up @@ -923,9 +961,12 @@ Finally, :ref:`GeoDjango's documentation <ref-contrib-gis>` is now
included with Django's and is no longer
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
replaced by the more common language code ``nb``, which should be updated
by translators from now on.
JavaScript-assisted handling of inline related objects in the admin
-------------------------------------------------------------------

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.
9 changes: 3 additions & 6 deletions docs/topics/forms/formsets.txt
Expand Up @@ -68,6 +68,8 @@ list of dictionaries as the initial data.

:ref:`Creating formsets from models with model formsets <model-formsets>`.

.. _formsets-max-num:

Limiting the maximum number of forms
------------------------------------

Expand All @@ -83,19 +85,14 @@ limit the maximum number of empty forms the formset will display::

.. 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,
so long as the total number of forms does not exceed ``max_num``.

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
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
------------------

Expand Down
4 changes: 2 additions & 2 deletions docs/topics/forms/modelforms.txt
Expand Up @@ -661,8 +661,8 @@ Limiting the number of editable objects

.. versionchanged:: 1.2

As with regular formsets, you can use the ``max_num`` parameter to
``modelformset_factory`` to limit the number of extra forms displayed.
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::

Expand Down
6 changes: 6 additions & 0 deletions tests/modeltests/model_formsets/models.py
Expand Up @@ -368,16 +368,22 @@ def __unicode__(self):
>>> AuthorFormSet = modelformset_factory(Author, max_num=None, extra=3)
>>> formset = AuthorFormSet(queryset=qs)
>>> len(formset.forms)
6
>>> len(formset.extra_forms)
3
>>> AuthorFormSet = modelformset_factory(Author, max_num=4, extra=3)
>>> formset = AuthorFormSet(queryset=qs)
>>> len(formset.forms)
4
>>> len(formset.extra_forms)
1
>>> AuthorFormSet = modelformset_factory(Author, max_num=0, extra=3)
>>> formset = AuthorFormSet(queryset=qs)
>>> len(formset.forms)
3
>>> len(formset.extra_forms)
0
Expand Down
46 changes: 45 additions & 1 deletion tests/regressiontests/forms/formsets.py
Expand Up @@ -599,14 +599,32 @@
# 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)
>>> 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>
# 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)
>>> formset = LimitedFavoriteDrinkFormSet()
Expand All @@ -616,6 +634,32 @@
# 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
# them to be displayed with no extra forms.
Expand Down

0 comments on commit d0d3e67

Please sign in to comment.