diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index cb87ebb1a2..7f972b224f 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -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`` ~~~~~~~~~ @@ -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`` ~~~~~~~~~~~ diff --git a/docs/releases/1.2.txt b/docs/releases/1.2.txt index d06e92ff88..1d4e78f3c0 100644 --- a/docs/releases/1.2.txt +++ b/docs/releases/1.2.txt @@ -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() ` and +:ref:`django.forms.models.modelformset_factory() +` functions has changed slightly. This +change also affects the way the ``max_num`` argument is :ref:`used for +inline admin objects ` + +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 ` 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 @@ -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 @@ -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 ======================== @@ -923,9 +961,12 @@ Finally, :ref:`GeoDjango's documentation ` is now included with Django's and is no longer hosted separately at `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. diff --git a/docs/topics/forms/formsets.txt b/docs/topics/forms/formsets.txt index e1af237598..732fd93de1 100644 --- a/docs/topics/forms/formsets.txt +++ b/docs/topics/forms/formsets.txt @@ -68,6 +68,8 @@ list of dictionaries as the initial data. :ref:`Creating formsets from models with model formsets `. +.. _formsets-max-num: + Limiting the maximum number of forms ------------------------------------ @@ -83,7 +85,7 @@ 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``. @@ -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 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 ------------------ diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index 066545756f..c93527ce70 100644 --- a/docs/topics/forms/modelforms.txt +++ b/docs/topics/forms/modelforms.txt @@ -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:: diff --git a/tests/modeltests/model_formsets/models.py b/tests/modeltests/model_formsets/models.py index 6d5b81dd8a..d5825313ec 100644 --- a/tests/modeltests/model_formsets/models.py +++ b/tests/modeltests/model_formsets/models.py @@ -368,16 +368,22 @@ the creation of new inlines beyond max_num. >>> 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 diff --git a/tests/regressiontests/forms/formsets.py b/tests/regressiontests/forms/formsets.py index ec7fc9ba11..fade987c26 100644 --- a/tests/regressiontests/forms/formsets.py +++ b/tests/regressiontests/forms/formsets.py @@ -599,6 +599,24 @@ True # 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 + + + + +# 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: @@ -606,7 +624,7 @@ True -# 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() @@ -616,6 +634,32 @@ True # 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 + + + +# 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.