# Hidden empty form on formset for InlineAdminForm

**URL:** <https://forum.djangoproject.com/t/hidden-empty-form-on-formset-for-inlineadminform/38520>\
**Category:** The Admin\
**Created:** [February 3, 2025, 5:34pm UTC](https://forum.djangoproject.com/t/hidden-empty-form-on-formset-for-inlineadminform/38520 "2025-02-03T17:34:17Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![evildmp](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/evildmp/32/23487_2.png) [@evildmp](https://forum.djangoproject.com/u/evildmp)\
**Post date:** [February 3, 2025, 5:34pm UTC](https://forum.djangoproject.com/t/hidden-empty-form-on-formset-for-inlineadminform/38520/1 "2025-02-03T17:34:17Z")

</div>

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:

```auto
>>> 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:

```auto
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](https://docs.djangoproject.com/en/5.1/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.formset), it makes no difference at all to the behaviour of the `InlineModelAdmin`.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [February 3, 2025, 6:44pm UTC](https://forum.djangoproject.com/t/hidden-empty-form-on-formset-for-inlineadminform/38520/2 "2025-02-03T18:44:39Z")

</div>

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`](https://docs.djangoproject.com/en/5.1/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.has_add_permission) on the class to set it `False`.  
e.g.

```auto
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.

---

<div class="post-metadata">

**Author:** ![evildmp](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/evildmp/32/23487_2.png) [@evildmp](https://forum.djangoproject.com/u/evildmp)\
**Post date:** [February 3, 2025, 8:20pm UTC](https://forum.djangoproject.com/t/hidden-empty-form-on-formset-for-inlineadminform/38520/3 "2025-02-03T20:20:41Z")

</div>

> [@KenWhitesell](#):
>
> ```auto
> class MyInline(admin.TabularInline):
> model = ChildModel
> 
> def has_add_permission(self, request, obj):
> return False
> 
> ```

And that seems to be exactly the thing, thanks!
