CodeOath
← All posts
Python65 min total · 18 parts

Django Fundamentals: The ORM, Migrations, and Shipping a Real App

Part 13 of 18 · ~1 min

The Admin Site, and the Same N+1 Bug Showing Up Twice

@admin.register(Loan)
class LoanAdmin(admin.ModelAdmin):
    list_display = ["id", "tool", "borrower", "status", "due_date"]
    list_filter = ["status"]
    search_fields = ["tool__name", "borrower__username"]
    list_select_related = ["tool", "borrower"]    # the admin list view is a loop over rows too

Register a model and /admin/ gives you a working CRUD interface for it with no view or template written by hand — genuinely one of Django's strongest wins for anything internal, since "some way for a non-engineer to look at and fix the data" is usually the very first real requirement any new feature turns out to have. It's worth noticing that the admin's changelist page is, mechanically, exactly the same for loop over rows that broke the browse page in chapter six — and when ToolShed's volunteer moderators had logged a few hundred loans, the admin's own loan list started dragging for the identical reason. list_select_related is select_related wearing an admin-specific name; leave it off and every row's tool and borrower columns cost their own separate query, same bug, different page.