Hidden empty form on formset for InlineAdminForm

In the page for a ModelAdmin with an inline, the inline formset will always inlcude one more extra inline than I asked for. (It’s hidden by the admin page’s CSS and has the class empty-form) .

Even if extra = 0 on the InlineModelAdmin, this form is added to the formset.

The extra form is not present in the formset itself when it’s first created. For example:

>>> FormSet = inlineformset_factory(ParentModel, ChildModel, fields="__all__", extra=0) # create a FormSet class
>>> fs = FS(instance= ParentModel.objects.get(pk=1))  # create a formset instance

I get the expected number of inline admin forms (i.e. 0), with no hidden extras.

Why is this extra inline form created, and how do I get rid of it?

I thought if it might be related to edit_only, and whether:

class MyInline(admin.TabularInline):
    model = ChildModel
    formset = inlineformset_factory(ParentModel, ChildModel, extra=0, edit_only=True, fields="__all__")

would remove it - but while that seems to be the way to use a custom formset on an inline, it makes no difference at all to the behaviour of the InlineModelAdmin.

This appears to be an artifact of the template, created by having the has_add_permission on the TabularInline class. (see django.contrib.admin.templates.admin.edit_inline - tabular.html)

I don’t know right off-hand if you can just add a has_add_permission=False attribute to MyInline - I don’t think it’s going to work because I believe the __init__ method for that class would override it.

My guess is you would need to override has_add_permission on the class to set it False.
e.g.

class MyInline(admin.TabularInline):
  model = ChildModel

  def has_add_permission(self, request, obj):
    return False

Again - I’ve never tried anything like this, it’s all conjecture at this point.

And that seems to be exactly the thing, thanks!