[Django] #33111: Conditionally changing ModelAdmin inlines based on object's field breaks saving object in admin site when new inlines should appear

5 views
Skip to first unread message

Django

unread,
Sep 15, 2021, 8:55:06 AM9/15/21
to django-...@googlegroups.com
#33111: Conditionally changing ModelAdmin inlines based on object's field breaks
saving object in admin site when new inlines should appear
-----------------------------------------+------------------------
Reporter: joeli | Owner: nobody
Type: Bug | Status: new
Component: contrib.admin | Version: 3.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
Minimal example:

{{{
#!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.

Django

unread,
Sep 16, 2021, 1:05:20 AM9/16/21
to django-...@googlegroups.com
#33111: Conditionally changing ModelAdmin inlines based on object's field breaks
when changing object and new inlines should appear.
-------------------------------+------------------------------------

Reporter: joeli | Owner: nobody
Type: Bug | Status: new
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by Mariusz Felisiak):

* 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>

Django

unread,
Sep 16, 2021, 3:44:15 AM9/16/21
to django-...@googlegroups.com
#33111: Conditionally changing ModelAdmin inlines based on object's field breaks
when changing object and new inlines should appear.
-------------------------------+------------------------------------------
Reporter: joeli | Owner: Hasan Ramezani
Type: Bug | Status: assigned
Component: contrib.admin | Version: 3.2

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------------
Changes (by Hasan Ramezani):

* owner: nobody => Hasan Ramezani
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/33111#comment:2>

Django

unread,
Sep 16, 2021, 4:59:18 AM9/16/21
to django-...@googlegroups.com
#33111: Conditionally changing ModelAdmin inlines based on object's field breaks
when changing object and new inlines should appear.
-------------------------------+------------------------------------------
Reporter: joeli | Owner: Hasan Ramezani
Type: Bug | Status: assigned
Component: contrib.admin | Version: 3.2

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------------
Changes (by Hasan Ramezani):

* has_patch: 0 => 1


Comment:

[https://github.com/django/django/pull/14861 PR]

--
Ticket URL: <https://code.djangoproject.com/ticket/33111#comment:3>

Django

unread,
Sep 21, 2021, 7:14:25 AM9/21/21
to django-...@googlegroups.com
#33111: Conditionally changing ModelAdmin inlines based on object's field breaks
when changing object and new inlines should appear.
-------------------------------------+-------------------------------------

Reporter: joeli | Owner: Hasan
| Ramezani
Type: Bug | Status: assigned
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/33111#comment:4>

Django

unread,
Sep 21, 2021, 7:36:05 AM9/21/21
to django-...@googlegroups.com
#33111: Conditionally changing ModelAdmin inlines based on object's field breaks
when changing object and new inlines should appear.
-------------------------------------+-------------------------------------
Reporter: joeli | Owner: Hasan
| Ramezani
Type: Bug | Status: closed
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak <felisiak.mariusz@…>):

* 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>

Django

unread,
Sep 21, 2021, 7:36:20 AM9/21/21
to django-...@googlegroups.com
#33111: Conditionally changing ModelAdmin inlines based on object's field breaks
when changing object and new inlines should appear.
-------------------------------------+-------------------------------------
Reporter: joeli | Owner: Hasan
| Ramezani
Type: Bug | Status: closed
Component: contrib.admin | Version: 3.2

Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

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>

Reply all
Reply to author
Forward
0 new messages