Gathole
Gathole

Reputation: 932

Reverse Inlines in Django Admin

I have 2 models as follows. Now I need to inline Model A on Model B's page.

models.py

class A(models.Model):
    name = models.CharField(max_length=50)

class B(models.Model):
    name = models.CharField(max_length=50)
    a = models.ForeignKey(A)

admin.py

class A_Inline(admin.TabularInline):  
    model = A

class B_Admin(admin.ModelAdmin): 
    inlines = [A_Inline]

is that possible?? If yes please let me know..

Upvotes: 12

Views: 7616

Answers (4)

JaWe
JaWe

Reputation: 41

The OP's question seems to be on a forward relation, which is actually simple. but since the title says 'Reverse Inlines', I believe people will search here for a reverse inline solution. and...

I was shocked to see after hours of searching for hacks, that the answer is actually simple as that! You can use a reverse inline just as a regular forward inline:

Models.py

class Owner(models.model):
    name = models.CharField(max_length=50)

class House(models.model):
    owner = models.ForeignKey(Owner, on_delete=models.CASCADE)

Now to list inline all houses that belong to that owner:

Admin.py

class HouseInline(admin.TabularInline):  
    model = House

class OwnerAdmin(admin.ModelAdmin): 
    inlines = [HouseInline]

This actually worked for me!

Upvotes: 0

Jura Brazdil
Jura Brazdil

Reputation: 1100

Of course you can do this. Every relationship be it 1-1, m2m or FK will have a reverse accessor. (more on the FK reverse access here)

class A_Inline(admin.TabularInline):  
    model = A.b_set.through

class B_Admin(admin.ModelAdmin): 
    inlines = [A_Inline]

Upvotes: 2

wanjijul
wanjijul

Reputation: 252

You cannot do it as told by timmy O'Mahony. But you can make B inline in A if you want. Or maybe you can manipulate how django display it in

def unicode(self):

models.py

class A(models.Model):
    name = models.CharField(max_length=50)
    def __unicode__(self):
        return self.name

class B(models.Model):
    name = models.CharField(max_length=50)
    a = models.ForeignKey(A)

admin.py

class B_Inline(admin.TabularInline):  
    model = B
class A_Admin(admin.ModelAdmin):
    inlines = [
        B_Inline,
    ]
admin.site.register(A, A_Admin)
admin.site.register(B)

Or maybe you want to use many-to-many relationship?

models.py

class C(models.Model):
    name = models.CharField(max_length=50)
    def __unicode__(self):
        return self.name
class D(models.Model):
    name = models.CharField(max_length=50)
    cs = models.ManyToManyField(C)

admin.py

class C_Inline(admin.TabularInline):  
    model = D.cs.through
class D_Admin(admin.ModelAdmin):
    exclude = ("cs",)
    inlines = [
        C_Inline,
    ]
admin.site.register(C)
admin.site.register(D, D_Admin)

Upvotes: 1

Timmy O'Mahony
Timmy O'Mahony

Reputation: 53971

No, as A needs to have a ForeignKey to B to be used as an Inline. Otherwise how would the relationship be recorded once you save the inline A?

Upvotes: 0

Related Questions