Opened 10 years ago
Last modified 10 years ago
#24541 closed Cleanup/optimization
save_new_objects in ModelFromsets do not handle intitial data — at Version 5
Reported by: | Johannes Maron | Owned by: | nobody |
---|---|---|---|
Component: | Documentation | Version: | dev |
Severity: | Normal | Keywords: | modelformset |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
If you create a ModelFormSet
and pass initial
data for some forms, the forms are evaluated as has_changed
False.
All in all that is true, but it has the the side effect that the forms in the formset don't get saved, tho they contain data.
The error is here:
https://github.com/django/django/blob/master/django/forms/models.py#L777-L778
It should not only be checked for has_changed
but also for initial data.
Change History (5)
comment:1 by , 10 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 10 years ago
Resolution: | invalid |
---|---|
Status: | closed → new |
That does not work for ModelFormSets
as the pop initial
to initial_extra
and only except existing objects using the Queryset.
There currently is no way to create objects using a ModelFormSet
with initial data.
I get your point, about compatibility, but you should decide if this odd behavior is a bug or a feature. Personally it feels like a bug. Especially as Model and regular form sets handle initial data so differently. There is no consistent behavior nor any documentation about this.
comment:3 by , 10 years ago
Easy pickings: | unset |
---|
I had no trouble with this view:
from django.forms.models import modelformset_factory def test_view(request): qs = Poll.objects.none() PollFormSet = modelformset_factory(Poll, fields='__all__') if request.method == 'POST': formset = PollFormSet(request.POST, queryset=qs) if formset.is_valid(): formset.save() else: formset = PollFormSet(queryset=qs, initial=[ {'question': 'initial', 'pub_date': timezone.now()}]) return render(request, 'polls/manage.html', {'formset': formset})
Can you provide a snippet that demonstrates your problem?
comment:4 by , 10 years ago
As I said:
It does not work if your submitted are not yet created and you can't pass a queryset.
from django.forms.models import modelformset_factory def test_view(request): qs = Poll.objects.none() PollFormSet = modelformset_factory(Poll, fields='__all__') if request.method == 'POST': formset = PollFormSet(request.POST, initial=[{'question': 'Foo'}, {'question': 'Bar'}]) if formset.is_valid(): obj_list = formset.save() assert len(obj_list) == 2 else: formset = PollFormSet(queryset=qs, initial=[ {'question': 'initial', 'pub_date': timezone.now()}]) return render(request, 'polls/manage.html', {'formset': formset})
This will fail.
comment:5 by , 10 years ago
Description: | modified (diff) |
---|
You should use initial forms instead of extra forms if you require those populated forms to be submitted. Changing the behavior to validate and save unchanged extra forms would be backwards incompatible. Feel free to reopen if I missed something.