The Django Admin: Instant CRUD for Free
Food Tracker (Django)
Chapter 3 · The Django Admin: Instant CRUD for Free
Chapter 1 promised a working CRUD interface before writing any business logic at all. Here's that promise, delivered.
Registering the Model
createsuperuser creates the admin's own login account — a separate concept entirely from any future end-user account this app might have. Visiting /admin/ and signing in with it now shows a complete, working list/add/edit/delete interface for Item, generated from just those two lines of code.
Customizing It With ModelAdmin
Plain registration gives a genuinely functional but generic list view. A ModelAdmin subclass shapes it into something actually useful day to day:
list_display— which columns actually show in the list view, instead of just each row's__str__.list_filter— a sidebar of quick filters, genuinely useful for jumping straight to, say, everything withstatus = "active".search_fields— the admin's own search box, which performs a real substring (SQLLIKE) match by default. Worth flagging honestly: this is a happy coincidence, not the same thing as the live search-as-you-type feature this course builds for the app itself later — the admin's search exists purely for the admin's own list view.readonly_fields—added_atis already non-editable (Chapter 2'sauto_now_addimplicitly setseditable=False), and Django's admin would normally just omit a non-editable field from the form entirely. Listing it inreadonly_fieldsinstead keeps its actual value visible — read-only — right there in the change form, rather than making it invisible.
A Real Tool, Not Just a Demo
Before Chapter 4's barcode lookup or Chapter 5's real add-item flow exist, this admin already lets real test Item rows be created by hand — genuinely useful for exercising Chapter 7's expiry query, or Chapter 8's search, against real data long before the app's own user-facing screens are built.
A Real Limit Worth Naming
The admin is a tool for whoever manages the site's data directly — it was never meant to be, and won't become, the pantry app's own end-user interface. There's no camera scanning here, no barcode-triggered lookup, no live search-as-you-type UX. Having a working admin is not the same as having a finished app; the two serve genuinely different audiences.
admin.py. This is exactly the "batteries included" tradeoff Chapter 1 named, made concrete rather than abstract.
list_editablelist_editable = ("status",) lets specific fields be edited directly from the list view itself, without opening the full change form — useful for a quick bulk "mark several as used" pass, once there's real data to try it on.
/admin/ is a powerful, largely unrestricted interface for anyone who successfully logs in — it isn't sandboxed the way the app's own end-user views might be. Real deployment deserves real consideration here: a genuinely strong password, restricting network access to it where feasible, and third-party two-factor packages are all common, real mitigations — treating the admin as purely a development convenience with no real-world exposure risk, once it's live, would be a mistake.
Where This Course Is Headed
Barcode lookup via a Django view, camera-based scanning, the add-item flow via Django Forms, expiry alerts, item history and search, marking items used, recipe lookup, Django REST Framework, deployment, and a capstone.
Hands-On Exercises
Explain what admin.site.register(Item) alone provides, and what a customized ModelAdmin subclass adds on top of it. Why do list_display, list_filter, and search_fields matter in practice rather than just being nice-to-haves?
📄 View solutionExplain why readonly_fields is still useful for added_at, given that auto_now_add already makes the field non-editable via editable=False.
📄 View solutionExplain the real security consideration this chapter raises about exposing /admin/ on a public deployment, and name at least two real mitigations it mentions.
📄 View solutionChapter 3 Quick Reference
admin.site.register(Item)— a full generic CRUD interface, two lines of codeModelAdmin—list_display,list_filter,search_fields,readonly_fieldsshape it into something actually usable- The admin's search ≠ the app's own live search — a happy coincidence of substring matching, not the same feature built later
- A dev tool, not the end-user UI — no camera scanning, no live search UX, a genuinely different audience
- Real production consideration — a public
/admin/needs a real password policy, restricted access, or 2FA - Next chapter: Barcode Lookup: Integrating Open Food Facts