Question
Answer and Explanation
To create a Django TabularInline with a link to the detail view, you need to customize the TabularInline
template. Here's how you can achieve this:
1. Understand Django's TabularInline:
- A TabularInline
is used in the Django admin to display related objects in a tabular format directly within the parent object's change form. By default, it doesn't provide links to the detail view of the related objects.
2. Override the `TabularInline` Template:
- Django allows you to override default admin templates. You can create a custom template for your TabularInline
to add the desired links.
3. Create a Custom `TabularInline` Class:
- Define a custom TabularInline
class that sets your custom template.
4. Example Code:
First, let's define your models. Suppose you have a `Parent` model and a related `Child` model:
# models.py
from django.db import models
class Parent(models.Model):
name = models.CharField(max_length=200)
class Child(models.Model):
parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='children')
name = models.CharField(max_length=200)
Next, create a custom template called admin/edit_inline/tabular.html
in your app's template directory, the one that contains the app `templates` directory in the same folder with `models.py`:
{% raw %}
{# admin/edit_inline/tabular.html #}
{% extends "admin/edit_inline/tabular.html" %}
{% block row %}
{% for field in inline_admin_form.fields %}
{% if field.name == 'name' %}
{{ field.contents }}
{% else %}
{{ field.field }}
{% endif %}
{% endfor %}
{% endblock %}
{% endraw %}
Create get_absolute_url
in your Child
model to provide the detail view url:
# models.py
from django.db import models
from django.urls import reverse
class Parent(models.Model):
name = models.CharField(max_length=200)
class Child(models.Model):
parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='children')
name = models.CharField(max_length=200)
def get_absolute_url(self):
return reverse('admin:yourapp_child_change', args=[str(self.id)])
Finally, create custom TabularInline
and register the Child
model in your admin.py
:
# admin.py
from django.contrib import admin
from .models import Parent, Child
class ChildInline(admin.TabularInline):
model = Child
template = 'admin/edit_inline/tabular.html'
@admin.register(Parent)
class ParentAdmin(admin.ModelAdmin):
inlines = [ChildInline]
@admin.register(Child)
class ChildAdmin(admin.ModelAdmin):
pass
5. Explanation:
- The custom admin/edit_inline/tabular.html
extends Django’s original tabular template and overrides the `row` block.
- The `field.name == 'name'` condition will wrap the name of the child to a link. If there are other fields, it will render them normally
- The `inline_admin_form.original` provides access to the original object instance which is the `Child` object in this example.
- We use `get_absolute_url` method defined in the `Child` model to create link to detail view of Child
object
By implementing this approach, each related object in the `TabularInline` will have a clickable link to its detail view in the Django admin.