Conditionally changing ModelAdmin inlines based on object's field breaks when changing object and new inlines should appear.
Minimal example:
# 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.
Change History
(6)
Cc: |
Hasan Ramezani WeizhongTu added
|
Summary: |
Conditionally changing ModelAdmin inlines based on object's field breaks saving object in admin site when new inlines should appear → Conditionally changing ModelAdmin inlines based on object's field breaks when changing object and new inlines should appear.
|
Triage Stage: |
Unreviewed → Accepted
|
Owner: |
changed from nobody to Hasan Ramezani
|
Status: |
new → assigned
|
Triage Stage: |
Accepted → Ready for checkin
|
Resolution: |
→ fixed
|
Status: |
assigned → closed
|
Thanks for the report. I was able to fix this issue by passing an old instance to the
get_inlines()
🤔: