Django (admin.e104) must inherit from 'InlineModelAdmin'

Viewed 6217

Trying to put some model as inline in the other two models gives some strange error (in title).

I have two models of orders - remote and local. And In each of them i need to insert products in some unlimited quantity. Another aim is to show full list of products ordered locally and remotely in different lists.

Solution for second aim: using second model of product inherited from first with it's own manager (objects).

Solutions for aim number one: to use inlines in admin classes of orders for appending exactly proper product in order (local product to local order and remote product to remote order).

Adding inline of local product to admin of local purchase works great. But adding inline of remote product to inlines field of admin file of remote order returns error for admin class of remote order:

must inherit from 'InlineModelAdmin'.

It also returns error even after removing inline from admin file of local order.

Some code like this in models.py:

class RemotePurchaseModel(models.Model):
    title = models.CharField
    number = models.IntegerField
    ...

class LocalPurchaseModel(models.Model):
    title = models.CharField
    number = models.IntegerField
    ...

class LocalProductModel(models.Model):
    remote = models.BooleanField(default=False)
    actual_order = models.ForeignKey(to=LocalPurchaseModel, blank=True, null=True)
    remote_purchase = models.ForeignKey(to=RemotePurchaseModel, blank=True, null=True)
    ...

class RemoteProductManager(djando.db.models.Manager):
    def get_queryset(self):
        return super(PurchasedProductManager, self).get_queryset().filter(remote=True)

class RemoteProductModel(LocalProduct):
    proxy = True
    objects = RemoteProductManager
    ...

...

in admin.py

from .models import LocalProductModel
from .models import RemoteProductModel
from .models import LocalPurchaseModel
from .models import RemotePurchaseModel
from django.contrib import admin

class LocalProductInline(admin.StackedInline):
    model = LocalProductModel
    extra = 1

class RemoteProductInline(admin.StackedInline):
    model = RemoteProductModel
    extra = 1

class LocalPurchaseAdmin(admin.ModelAdmin):
    list_display = ...
    fields = ...
    inlines = (LocalProductInline, )

class RemotePurchaseAdmin(admin.ModelAdmin):
    list_display = ...
    fields = ...
    inlines = (RemoteProductInline, )

...
admin.site.register(LocalPurchaseModel, LocalPurchaseAdmin)
admin.site.register(RemotePurchaseModel, RemotePurchaseAdmin)

And also the reason of this variation is two show different set of fields for local and remote products in admin side. Of course all fields exist in LocalProductModel. Any clues? Thanks.

5 Answers

My stupid mistake was that I had the inline class name inside quotes.

instead of:

class MyAdmin(admin.ModelAdmin):
    inlines = [MyInlineAdmin]

it was:

class MyAdmin(admin.ModelAdmin):
    inlines = ['MyInlineAdmin']

Total Cost:

  • 2 Hours
  • Some scratches on the laptop screen
  • Less swimming today in the sea

Found the reason. In actual code, which is not mine originally, names of models are the same as names of files they are placed in. Son at some step of checking Django (or python) detects inheritance of RemoteProductModel from LocalProductModel as error - like inheritance from file, not class-model. And after that it cannot work with it's fields and of course RemotePurchaseAdmin cannot make import as inline as model if remote product. It does not warn about inheritance error but raieses admin.E104 for admin.ModelAdmin, that tried to import incorrect model or inline.

Thanks everyone. Hope this will warn other developers from stupid mistakes.

Yes the problem is the model name has changed, I solve this running makemigrations and migrate

I made a variation of the same mistake.

My inline was:

class MyModelInline(admin.StackedInline):
    model = MyModel

But I referred to the inline by the model name, not the inline name:

@admin.register(OtherModel)
class OtherModelAdmin(admin.ModelAdmin):
    inlines = [MyModel]

Whereas it should have been:

@admin.register(OtherModel)
class OtherModelAdmin(admin.ModelAdmin):
    inlines = [MyModelInline]

That mistake was generating the following error:

ERRORS:
<class 'app_name.admin.OtherModelAdmin'>: (admin.E104) 'app_name.models.models_file.MyModel' must inherit from 'InlineModelAdmin'.

It's obvious once you see it...

enter image description here

Notice the accidental comma outside of the inlines list? That triggers the warning too.

Related