ModelAdmin basics
coreintermediateModelAdmin configures how ONE model appears and behaves in the admin. list_display picks the columns shown on the list page (fields, related-field lookups like "author__name", or a method taking the instance). list_filter adds a sidebar of filters; search_fields (icontains by default, with ^/=/@ prefixes for other lookup types) adds a search box. ordering sets the default sort; readonly_fields displays a field without letting it be edited; fieldsets groups the edit form's fields into labeled sections instead of one flat list.
Think of it as
ModelAdmin is a whole separate configuration OBJECT sitting between a model and the admin's generated pages — none of these attributes touch the model itself, they only describe how the admin should present and let staff interact with it. list_display is specifically about the LIST page's columns; it accepts three different kinds of things (a field name, a dunder-traversal to a related field, or a callable/method) precisely because "what should this column show" is sometimes a raw value, sometimes something computed. fieldsets exists because a flat form listing every field, in whatever order the model happens to declare them, is often not how a human actually wants to fill the form out — grouping related fields together, with some sections collapsed by default (via classes=["collapse"]), is purely a presentation decision layered on top of the same underlying fields.
What we're doing: Configure a readable admin for Article — searchable, filterable, with a computed status column and a collapsed "advanced" section on the edit form.
- 5
- "^slug" searches slug with istartswith, not the default icontains — appropriate for a slug, where a prefix match is usually what a staff user actually wants.
- 10
- "Advanced" fieldset uses classes=["collapse"] — those fields are hidden behind a clickable header by default, keeping the common edit path focused on the fields most people actually need.
Why this works: A flat list of every Article field (title, slug, author, meta_description, og_image, ...) would bury the fields editors touch daily among ones they rarely need — fieldsets with a collapsed "Advanced" section keeps the common case fast while still making the less-common fields reachable.
Adding a ManyToManyField directly to list_display, expecting it to just work like a ForeignKey
Wrong
Better
What you see: django.core.exceptions.ImproperlyConfigured (or a similar validation error) raised when Django's admin system checks run, specifically flagging the ManyToManyField in list_display.
Why: A ForeignKey/OneToOneField has exactly one related object, so its __str__() is a cheap, single value to show — a ManyToManyField could have any number of related objects, and showing them all would mean a SEPARATE query per row on the changelist page (a real N+1 risk), which Django refuses to do implicitly. A method that explicitly joins the related objects into a display string (accepting the query cost deliberately) is the documented workaround.
- Whole: class ArticleAdmin(admin.ModelAdmin): list_display = ["title", "author", "status"] list_filter = ["status"] search_fields = ["title", "author__email"] ordering = ["-published_at"] readonly_fields = ["created_at"]
- list_display — list_display: which columns appear on the changelist page
- list_filter — list_filter: the sidebar filter widgets
- search_fields — search_fields: which fields the search box queries, and how
- ordering — ordering: the default sort order for the changelist
- readonly_fields — readonly_fields: shown on the change form but not editable
The core ModelAdmin list/search/form options
Together
Remember: list_display accepts fields, related-field lookups (__), or callables — never a ManyToManyField directly (a real N+1 risk Django refuses to do implicitly). search_fields defaults to icontains; ^/=/@ prefixes switch to istartswith/iexact/full-text. fieldsets groups the edit form into labeled, optionally-collapsed sections.
See also: inlines actions and permissions · admin performance and query optimization · retrieval methods

