Commit e308cfc0 authored by Ramiro Morales's avatar Ramiro Morales
Browse files

Added support for specifying initial values to model formsets and inline formsets.

This make them consistent with the similar capability of regular
formsets. Thanks to simon29 form the report and to Claude Paroz for the
patch.

Fixes #14574.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17373 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 4e29b70b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ class BaseFormSet(StrAndUnicode):
        if self.is_bound:
            defaults['data'] = self.data
            defaults['files'] = self.files
        if self.initial:
        if self.initial and not 'initial' in kwargs:
            try:
                defaults['initial'] = self.initial[i]
            except IndexError:
+9 −2
Original line number Diff line number Diff line
@@ -418,6 +418,7 @@ class BaseModelFormSet(BaseFormSet):
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 queryset=None, **kwargs):
        self.queryset = queryset
        self.initial_extra = kwargs.pop('initial', None)
        defaults = {'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix}
        defaults.update(kwargs)
        super(BaseModelFormSet, self).__init__(**defaults)
@@ -448,6 +449,12 @@ class BaseModelFormSet(BaseFormSet):
            kwargs['instance'] = self._existing_object(pk)
        if i < self.initial_form_count() and not kwargs.get('instance'):
            kwargs['instance'] = self.get_queryset()[i]
        if i >= self.initial_form_count() and self.initial_extra:
            # Set initial values for extra forms
            try:
                kwargs['initial'] = self.initial_extra[i-self.initial_form_count()]
            except IndexError:
                pass
        return super(BaseModelFormSet, self)._construct_form(i, **kwargs)

    def get_queryset(self):
@@ -674,7 +681,7 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None,
class BaseInlineFormSet(BaseModelFormSet):
    """A formset for child objects related to a parent."""
    def __init__(self, data=None, files=None, instance=None,
                 save_as_new=False, prefix=None, queryset=None):
                 save_as_new=False, prefix=None, queryset=None, **kwargs):
        from django.db.models.fields.related import RelatedObject
        if instance is None:
            self.instance = self.fk.rel.to()
@@ -687,7 +694,7 @@ class BaseInlineFormSet(BaseModelFormSet):
            queryset = self.model._default_manager
        qs = queryset.filter(**{self.fk.name: self.instance})
        super(BaseInlineFormSet, self).__init__(data, files, prefix=prefix,
                                                queryset=qs)
                                                queryset=qs, **kwargs)

    def initial_form_count(self):
        if self.save_as_new:
+6 −0
Original line number Diff line number Diff line
@@ -556,6 +556,12 @@ Django 1.4 also includes several smaller improvements worth noting:
* The MySQL database backend can now make use of the savepoint feature
  implemented by MySQL version 5.0.3 or newer with the InnoDB storage engine.

* It is now possible to pass initial values to the model forms that are part of
  both model formsets and inline model formset as returned from factory
  functions ``modelformset_factory`` and ``inlineformset_factory`` respectively
  just like with regular formsets. However, initial values only apply to extra
  forms i.e. those which are not bound to an existing model instance.

Backwards incompatible changes in 1.4
=====================================

+2 −0
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ Formsets can also be indexed into, which returns the corresponding form. If you
override ``__iter__``, you will need to also override ``__getitem__`` to have
matching behavior.

.. _formsets-initial-data:

Using initial data with a formset
---------------------------------

+11 −0
Original line number Diff line number Diff line
@@ -617,6 +617,17 @@ exclude::

    >>> AuthorFormSet = modelformset_factory(Author, exclude=('birth_date',))

Providing initial values
------------------------

.. versionadded:: 1.4

As with regular formsets, it is possible to :ref:`specify initial data
<formsets-initial-data>` for forms in the formset by specifying an ``initial``
parameter when instantiating the model formset class returned by
``modelformset_factory``. However, with model formsets the initial values only
apply to extra forms, those which are not bound to an existing object instance.

.. _saving-objects-in-the-formset:

Saving objects in the formset
Loading