Django admin inlines allow you to edit related models on the same page as the parent model in the admin interface.

They're useful when you have parent-child relationships between models and want to manage them together.

from django.contrib import admin

class OrderItemInline(admin.TabularInline):  # or admin.StackedInline for a different layout
    model = OrderItem
    extra = 1  # number of empty forms to display
    raw_id_fields = ('product',)  # adds a lookup widget for product selection

class OrderAdmin(admin.ModelAdmin):
    list_display = ('id', 'customer', 'created_dt', 'status')
    list_filter = ('status',)
    readonly_fields = ('created_dt', 'completed_dt')
    inlines = [OrderItemInline]

admin.site.register(Order, OrderAdmin)

TabularInline example:

Django Admin TabularInline

StackedInline example:

Django Admin StackedInline

Let's add another inline for orders and place it into the CustomerAdmin.

First let's add show_change_link = True and it will display a link to the Order.

class LatestOrdersInline(admin.TabularInline):
    model = Order
    fields = ("id", "created_dt", "status")
    readonly_fields = ("id", "created_dt", "status")
    extra = 0
    ordering = ("-created_dt",)
    show_change_link = True


class CustomerAdmin(admin.ModelAdmin):
    list_display = (
        "first_name",
        "last_name",
        "phone",
        "id",
    )
    inlines = [LatestOrdersInline]


admin.site.register(Customer, CustomerAdmin)

Django InlineAdmin show_change_link

How to do Django admin inline Queryset limit

You can override get_queryset(request) method in admin.TabularInline and admin.StackedInline.

Unfortunately, if you make a slice like this super().get_queryset(request).order_by('-id')[:10] it would lead to an error:

TypeError at /admin/myapp/customer/1/change/ Cannot filter a query once a slice has been taken.

So what you have to do is to make two queries:

  • One to get IDs of the desired records
  • another to fetch records with IDs from the first query.
class LatestOrdersInline(admin.TabularInline):
    model = Order
    fields = ("id", "created_dt", "status")
    readonly_fields = ("id", "created_dt", "status")
    extra = 0
    ordering = ("-created_dt",)
    show_change_link = True
    verbose_name = 'Latest Orders'

    def get_queryset(self, request):
        ids = (
            super()
            .get_queryset(request)
            .order_by("-created_dt")
            .values_list("id", flat=True)[:5]
        )
        qs = super().get_queryset(request).filter(id__in=ids).order_by("-created_dt")
        return qs


class CustomerAdmin(admin.ModelAdmin):
    list_display = (
        "first_name",
        "last_name",
        "phone",
        "id",
    )
    inlines = [LatestOrdersInline]


admin.site.register(Customer, CustomerAdmin)

django admin inline queryset limit

Also we have changed the name of the Django Admin Inline block using verbose_name to "Latest Orders"