seddonym
seddonym

Reputation: 17229

How can I add inlines to the ModelAdmin of another app, without a circular dependency?

Let's say I have two models, in different apps. App Two knows about app One, but not the other way around:

# one/models.py

from django.db import models

class One(models.Model):
    pass


# two/models.py

from django.db import models
from one.models import One

class Two(models.Model):
    one = models.ForeignKey(One)

I also have One registered in the admin site:

# one/admin.py

from django.contrib import admin
from .models import One

admin.site.register(One)

How do I register Two as an Inline on One's admin page, without introducing a circular dependency between the two apps?

Upvotes: 5

Views: 947

Answers (3)

stasdavydov
stasdavydov

Reputation: 383

I had the same issue but solved it more gentle way.

# one/admin.py

class OneAdmin(admin.ModelAdmin):
    model = One

admin.site.register(One, OneAdmin)

# two/admin.py

class TwoInline(admin.TabularInline):
    model = Two

import one.admin
class OneAdmin(one.admin.OneAdmin):
    inlines = [TwoInline]

admin.site.unregister(One)
admin.site.register(One, OneAdmin)

As you see I extended the original ModelAdmin from first app and added inlines from second app. Don't forget to unregister the model from first app before registering it again. It's safe and much better than to access private member of the class as was suggested.

Upvotes: 5

raratiru
raratiru

Reputation: 9616

I would try the following:

# one/admin.py
from django.contrib import admin
from one.models import One
from two.models import Two

class TwoInline(admin.StackedInline):
    model = Two

class OneAdmin(admin.ModelAdmin):
    inlines = [TwoInline,]

admin.site.register(One, OneAdmin)

You can read more at the docs.

Upvotes: 0

seddonym
seddonym

Reputation: 17229

You can do this pretty simply, providing you don't mind accessing a 'private' attribute on the ModelAdmin. (Attributes beginning with an underscore are treated as private by convention.)

# two/admin.py
from django.contrib import admin
from one.models import One
from .models import Two

class TwoInline(admin.StackedInline):
    model = Two

admin.site._registry[One].inlines.append(TwoInline)

Upvotes: 6

Related Questions