Dynamic inlines in django admin

I have two models:

  1. PrimaryModel. Has a choice value (Alive/Finished)
  2. AuxModel. Has a foreign key for the PrimaryModel and only is showed when the status of the primary model is equal to “Finished”.
# Model.py
from django.db import models

# Create your models here.
class PrimaryModel(models.Model):
    class Status(models.TextChoices):
        ALIVE = 'Alive', 'Alive'
        FINISHED = 'Finished', 'Finished'

    status = models.CharField(choices=Status.choices, default=Status.ALIVE, max_length=15)


class AuxModel(models.Model):
    primary = models.ForeignKey(PrimaryModel, on_delete=models.CASCADE)
    campo = models.CharField(max_length=15)

I have decided to make the logic to show/hide the inline in the backend through get_inlines (it sounded easy) so i make this:

# admin.py
from django.contrib import admin
from .models import AuxModel, PrimaryModel


class AuxInline(admin.StackedInline):
    model = AuxModel


@admin.register(PrimaryModel)
class PrimaryAdmin(admin.ModelAdmin):
    fields = ('status',)

    def get_inlines(self, request, obj):
        if obj and obj.status == PrimaryModel.Status.FINISHED:
            return [AuxInline]
        return []

This works great when i create a new object but when i intent to change the status to FINISHED, the inlines show this error and cancel the change

(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: auxmodel_set-TOTAL_FORMS, auxmodel_set-INITIAL_FORMS. You may need to file a bug report if the issue persists.

This is a strange error because i only modify the get_inlines. if it helps, I’m using Django 3.2

No, this are the only changes that i apply to the base project generated by django-admin (and add the app to the settings file). In my original problem I was doing it but saw the same behavior occur in a simple project like this.

Note. The new project was generated in a new virtual environment created with venv

Ok, so the issue here is that when you POST the status change back to the form, it rebuilds the form - including calling get_inlines - which how has the status FINISHED, and so builds the form object with the inlines. However, the form originally rendered and displayed in the browser didn’t have those inlines in the form - and therefore didn’t have a management form rendered in it.
Since the posted form has the inlines defined, it’s trying to validate a management form that doesn’t exist.

Thanks, so the easiest way to get the result is modifying the frontend or adding a class ‘hide’ / ‘show’ in the fieldset?

Hmmm… Yea, if I had to do something like this, my first thought would be to write a little bit of JavaScript that would show/hide the inlines on the page based on the value of status.