# Django TabularInline through relationship

**URL:** <https://forum.djangoproject.com/t/django-tabularinline-through-relationship/3953>\
**Category:** The Admin\
**Created:** [August 18, 2020, 7:17am UTC](https://forum.djangoproject.com/t/django-tabularinline-through-relationship/3953 "2020-08-18T07:17:22Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![alexandernst](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/alexandernst/32/1882_2.png) [@alexandernst](https://forum.djangoproject.com/u/alexandernst)\
**Post date:** [August 18, 2020, 7:17am UTC](https://forum.djangoproject.com/t/django-tabularinline-through-relationship/3953/1 "2020-08-18T07:17:22Z")

</div>

Let’s say I have the following models:

```auto
class A(models.Model):
  pass

class B(models.Model):
  a = models.ForeignKey("A")

class C(models.Model):
  b = models.ForeignKey("B")

```

I can have a TabularInline widget showing all `B`s of a particular `A` like this:

```auto
class AAdmin(admin.ModelAdmin):
  inlines = [BInline]

class BInline(admin.TabularInline):
  model = B

```

How can I have a TabularInline widget showing all `C`s of a particular `A`? (all `C`s of all `B`s of a particular `A`)

I guess I’m looking for something like:

```auto
class AAmin(admin.ModelAdmin):
  inlines = [CInline]

class CInline(admin.TabularInline):
  model = C.through.B

```

Note: I know about the existence of `django-nested-admin`. this package will show all `C`s grouped by every `B`s, which is not what I want. I want to show only `C`s, without any references to `B`s.

---

<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:** [August 18, 2020, 12:57pm UTC](https://forum.djangoproject.com/t/django-tabularinline-through-relationship/3953/2 "2020-08-18T12:57:04Z")

</div>

From a relational model, that doesn’t really make sense, especially in the admin. How can you relate a C to an A in the absence of a B? (I’m more thinking of trying to add a new C.)  
(And if this is something being presented to a non-administrative user, why are you using the admin?)

Having said the above, you could probably achieve what you want by writing a [custom admin form](https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form) to display that list of related C.

---

<div class="post-metadata">

**Author:** ![alexandernst](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/alexandernst/32/1882_2.png) [@alexandernst](https://forum.djangoproject.com/u/alexandernst)\
**Post date:** [August 18, 2020, 1:11pm UTC](https://forum.djangoproject.com/t/django-tabularinline-through-relationship/3953/3 "2020-08-18T13:11:11Z")

</div>

It makes perfect sense for my use case. Model A is a bus line. Model B is a bus stop (a bus line has multiple bus stops). Model C is a physical object belonging to a bus stop.

I want to show all physical objects of bus line X. I don’t really need to edit or add new physical objects, only show the existing ones.

---

<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:** [August 18, 2020, 1:16pm UTC](https://forum.djangoproject.com/t/django-tabularinline-through-relationship/3953/4 "2020-08-18T13:16:16Z")

</div>

Then create your template and view to do this. That way you have complete control over what’s being displayed on the page, and you’re not fighting the admin to do it. If you’re not performing any edits or additions, this isn’t even a form.

This brings the issue down to the more common list view / detail view type of application, where the list view is the list of bus lines and the detail view is the list of physical objects. (Assuming you’d want to select the bus line from a list.)

---

<div class="post-metadata">

**Author:** ![alexandernst](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/alexandernst/32/1882_2.png) [@alexandernst](https://forum.djangoproject.com/u/alexandernst)\
**Post date:** [August 18, 2020, 1:29pm UTC](https://forum.djangoproject.com/t/django-tabularinline-through-relationship/3953/5 "2020-08-18T13:29:14Z")

</div>

I know… I was hoping there would be a way to avoid having to create all those files. I mean, if I want a view-only that can be easily represented with a “through” relation in the ORM model, why can’t django render a TabularInline-readonly widget with the data?

---

<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:** [August 18, 2020, 1:32pm UTC](https://forum.djangoproject.com/t/django-tabularinline-through-relationship/3953/6 "2020-08-18T13:32:12Z")

</div>

Because the admin isn’t designed nor intended to be an end-user reporting tool. You’re trying to use a screwdriver to drive nails.

---

<div class="post-metadata">

**Author:** ![alexandernst](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/alexandernst/32/1882_2.png) [@alexandernst](https://forum.djangoproject.com/u/alexandernst)\
**Post date:** [August 18, 2020, 1:48pm UTC](https://forum.djangoproject.com/t/django-tabularinline-through-relationship/3953/7 "2020-08-18T13:48:03Z")

</div>

In all fairness, TabularInlines already can be read-only (via de `readonly` attribute). And Django can already give me, easily, all `C`s from a given `A` using the ORM.

It seems fair enough to ask Django’s admin to combine those two things, and I’m fairly sure that this could actually be achieved with a small patch on Django’s side.

---

<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:** [August 18, 2020, 2:15pm UTC](https://forum.djangoproject.com/t/django-tabularinline-through-relationship/3953/8 "2020-08-18T14:15:58Z")

</div>

Excerpt from the official [Django admin site](https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#module-django.contrib.admin) documentation:

`<quote from the docs>`  
The admin’s recommended use is limited to an organization’s internal management tool. It’s not intended for building your entire front end around.

The admin has many hooks for customization, but beware of trying to use those hooks exclusively. If you need to provide a more process-centric interface that **abstracts away the implementation details of database tables and fields, then it’s probably time to write your own views.**  
`<end of quote - emphasis mine>`

If you wish to use the admin facility in this way, you already have the ability to define a custom form for the admin - you can make the admin display whatever you’d like. (Heaven knows, I’ve done it enough times myself in ways I’d rather not admit.)

And, if you feel that strongly about it, you can always file a ticket / submit a patch. (You probably should check the current set of tickets to see if this topic has already been discussed.) But as it is contrary to my understanding of the purpose of the admin, my opinion would be that it doesn’t belong there.
