diff --git a/django/forms/formsets.py b/django/forms/formsets.py
index 04057a1..a2c886c 100644
a
|
b
|
class BaseFormSet(StrAndUnicode):
|
119 | 119 | if self.is_bound: |
120 | 120 | defaults['data'] = self.data |
121 | 121 | defaults['files'] = self.files |
122 | | if self.initial: |
| 122 | if self.initial and not 'initial' in kwargs: |
123 | 123 | try: |
124 | 124 | defaults['initial'] = self.initial[i] |
125 | | except IndexError: |
| 125 | except (IndexError, KeyError): |
126 | 126 | pass |
127 | 127 | # Allow extra forms to be empty. |
128 | 128 | if i >= self.initial_form_count(): |
diff --git a/django/forms/models.py b/django/forms/models.py
index 254cca3..06cd53b 100644
a
|
b
|
class BaseModelFormSet(BaseFormSet):
|
417 | 417 | def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, |
418 | 418 | queryset=None, **kwargs): |
419 | 419 | self.queryset = queryset |
| 420 | self.initial_extra = kwargs.pop('initial', None) |
420 | 421 | defaults = {'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix} |
421 | 422 | defaults.update(kwargs) |
422 | 423 | super(BaseModelFormSet, self).__init__(**defaults) |
… |
… |
class BaseModelFormSet(BaseFormSet):
|
447 | 448 | kwargs['instance'] = self._existing_object(pk) |
448 | 449 | if i < self.initial_form_count() and not kwargs.get('instance'): |
449 | 450 | kwargs['instance'] = self.get_queryset()[i] |
| 451 | if i >= self.initial_form_count() and self.initial_extra: |
| 452 | # Set initial values for extra forms |
| 453 | try: |
| 454 | kwargs['initial'] = self.initial_extra[i-self.initial_form_count()] |
| 455 | except IndexError: |
| 456 | pass |
450 | 457 | return super(BaseModelFormSet, self)._construct_form(i, **kwargs) |
451 | 458 | |
452 | 459 | def get_queryset(self): |
… |
… |
def modelformset_factory(model, form=ModelForm, formfield_callback=None,
|
673 | 680 | class BaseInlineFormSet(BaseModelFormSet): |
674 | 681 | """A formset for child objects related to a parent.""" |
675 | 682 | def __init__(self, data=None, files=None, instance=None, |
676 | | save_as_new=False, prefix=None, queryset=None): |
| 683 | save_as_new=False, prefix=None, queryset=None, **kwargs): |
677 | 684 | from django.db.models.fields.related import RelatedObject |
678 | 685 | if instance is None: |
679 | 686 | self.instance = self.fk.rel.to() |
… |
… |
class BaseInlineFormSet(BaseModelFormSet):
|
686 | 693 | queryset = self.model._default_manager |
687 | 694 | qs = queryset.filter(**{self.fk.name: self.instance}) |
688 | 695 | super(BaseInlineFormSet, self).__init__(data, files, prefix=prefix, |
689 | | queryset=qs) |
| 696 | queryset=qs, **kwargs) |
690 | 697 | |
691 | 698 | def initial_form_count(self): |
692 | 699 | if self.save_as_new: |
diff --git a/docs/topics/forms/formsets.txt b/docs/topics/forms/formsets.txt
index 7912294..f021bb6 100644
a
|
b
|
Formsets can also be indexed into, which returns the corresponding form. If you
|
53 | 53 | override ``__iter__``, you will need to also override ``__getitem__`` to have |
54 | 54 | matching behavior. |
55 | 55 | |
| 56 | .. _formsets-initial-data: |
| 57 | |
56 | 58 | Using initial data with a formset |
57 | 59 | --------------------------------- |
58 | 60 | |
diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt
index 07c7b02..8b0ce31 100644
a
|
b
|
exclude::
|
613 | 613 | |
614 | 614 | >>> AuthorFormSet = modelformset_factory(Author, exclude=('birth_date',)) |
615 | 615 | |
| 616 | Providing initial values |
| 617 | ------------------------ |
| 618 | |
| 619 | .. versionadded:: 1.4 |
| 620 | |
| 621 | As with regular formsets, it is possible to :ref:`specify initial data |
| 622 | <formsets-initial-data>` for forms in the formset. However, with model formsets |
| 623 | the initial values only apply to extra forms, those which are not bound with an |
| 624 | existing object instance. |
| 625 | |
| 626 | |
616 | 627 | .. _saving-objects-in-the-formset: |
617 | 628 | |
618 | 629 | Saving objects in the formset |
diff --git a/tests/regressiontests/model_formsets_regress/tests.py b/tests/regressiontests/model_formsets_regress/tests.py
index e6c2633..7d5a756 100644
a
|
b
|
class InlineFormsetTests(TestCase):
|
202 | 202 | ["<Host: matrix.de.eu.dal.net>", "<Host: tranquility.hub.dal.net>"] |
203 | 203 | ) |
204 | 204 | |
| 205 | def test_initial_data(self): |
| 206 | user = User.objects.create(username="bibi", serial=1) |
| 207 | usersite = UserSite.objects.create(user=user, data=7) |
| 208 | Form = modelform_factory(User) |
| 209 | FormSet = inlineformset_factory(User, UserSite, extra=2) |
| 210 | |
| 211 | formset = FormSet(instance=user, initial=[{'data': 41}, {'data': 42}]) |
| 212 | self.assertEqual(formset.forms[0].initial['data'], 7) |
| 213 | self.assertEqual(formset.extra_forms[0].initial['data'], 41) |
| 214 | self.assertTrue(u'value="42"' in formset.extra_forms[1].as_p()) |
| 215 | |
| 216 | |
205 | 217 | class FormsetTests(TestCase): |
206 | 218 | def test_error_class(self): |
207 | 219 | ''' |
… |
… |
class FormsetTests(TestCase):
|
228 | 240 | self.assertTrue(isinstance(form.errors, ErrorDict)) |
229 | 241 | self.assertTrue(isinstance(form.non_field_errors(), ErrorList)) |
230 | 242 | |
| 243 | def test_initial_data(self): |
| 244 | user = User.objects.create(username="bibi", serial=1) |
| 245 | Formset = modelformset_factory(User, extra=2) |
| 246 | formset = Formset(initial=[{'username': u'apollo11'}, {'username': u'apollo12'}]) |
| 247 | self.assertEqual(formset.forms[0].initial['username'], "bibi") |
| 248 | self.assertEqual(formset.extra_forms[0].initial['username'], "apollo11") |
| 249 | self.assertTrue(u'value="apollo12"' in formset.extra_forms[1].as_p()) |
| 250 | |
231 | 251 | class CustomWidget(forms.CharField): |
232 | 252 | pass |
233 | 253 | |