{{{
#!python
# models.py
class Parent(models.Model):
show_inlines = models.BooleanField(default=False)
class Child(models.Model):
parent = models.ForeignKey(Parent, on_delete=models.CASCADE)
# admin.py
class ChildInline(admin.StackedInline):
model = Child
@admin.register(Parent)
class ParentAdmin(admin.ModelAdmin):
def get_inlines(self, request, obj):
if obj is not None and obj.show_inlines:
return [ChildInline]
return []
}}}
- Create `Parent` objects in either initial state and it works as you'd
expect, where `ChildInline` is rendered when `show_inlines` is True.
- When `show_inlines` is True, you can also set it to False from the admin
site, and the `ChildInline` disappears as expected.
- But when `show_inlines` is False, you cannot re-enable it. Saving the
object fails due to a validation error in the new `ChildInline` that
didn't exist before saving:
{{{
(Hidden field TOTAL_FORMS) This field is required.
(Hidden field INITIAL_FORMS) This field is required.
ManagementForm data is missing or has been tampered with. Missing fields:
child_set-TOTAL_FORMS, child_set-INITIAL_FORMS. You may need to file a bug
report if the issue persists.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/33111>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* cc: Hasan Ramezani, WeizhongTu (added)
* stage: Unreviewed => Accepted
Comment:
Thanks for the report. I was able to fix this issue by passing an old
instance to the `get_inlines()` 🤔:
{{{
diff --git a/django/contrib/admin/options.py
b/django/contrib/admin/options.py
index 1e5fab917e..7b2b893c10 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -1585,12 +1585,16 @@ class ModelAdmin(BaseModelAdmin):
)
if request.method == 'POST':
form = ModelForm(request.POST, request.FILES, instance=obj)
+ formsets, inline_instances = self._create_formsets(
+ request,
+ form.instance if add else obj,
+ change=not add,
+ )
form_validated = form.is_valid()
if form_validated:
new_object = self.save_form(request, form, change=not
add)
else:
new_object = form.instance
- formsets, inline_instances = self._create_formsets(request,
new_object, change=not add)
if all_valid(formsets) and form_validated:
self.save_model(request, new_object, form, not add)
self.save_related(request, form, formsets, not add)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/33111#comment:1>
* owner: nobody => Hasan Ramezani
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/33111#comment:2>
* has_patch: 0 => 1
Comment:
[https://github.com/django/django/pull/14861 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/33111#comment:3>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/33111#comment:4>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"2f0f30f973363a59c20f204f9351724fb2ce7327" 2f0f30f]:
{{{
#!CommitTicketReference repository=""
revision="2f0f30f973363a59c20f204f9351724fb2ce7327"
Fixed #33111 -- Fixed passing object to ModelAdmin.get_inlines() when
editing in admin change view.
ModelAdmin.get_inlines() should get an unmutated object when creating
formsets during POST request.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/33111#comment:5>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"668b990bf6da5232b16f979f59bb5d9b3af19e45" 668b990b]:
{{{
#!CommitTicketReference repository=""
revision="668b990bf6da5232b16f979f59bb5d9b3af19e45"
[4.0.x] Fixed #33111 -- Fixed passing object to ModelAdmin.get_inlines()
when editing in admin change view.
ModelAdmin.get_inlines() should get an unmutated object when creating
formsets during POST request.
Backport of 2f0f30f973363a59c20f204f9351724fb2ce7327 from main
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/33111#comment:6>