Model admins¶
A model admin controls how a model appears and behaves in the dashboard. All attributes are optional and mirror Django Admin where possible.
List page attributes¶
| Attribute | Default | Description |
|---|---|---|
list_display |
() |
Fields shown as columns on the list page. Without it, a single __str__ column is shown. |
list_display_links |
() |
Which list_display fields link to the change page. |
list_display_widths |
{} |
Column widths per field ({"id": "100px"}). |
list_filter |
() |
Fields that get a filter in the table columns. |
list_per_page |
10 |
Items per paginated page. |
list_max_show_all |
200 |
Max total count for which a "Show all" link is displayed. |
list_select_related |
() |
Relations passed to the ORM's select_related to save queries. |
ordering |
() |
Default ordering, e.g. ("-created_at",). |
preserve_filters |
True |
Keep applied filters after add/edit/delete. |
search_fields |
() |
Fields searched by the search box. |
search_help_text |
"" |
Help text under the search box. |
show_full_result_count |
False |
Show "99 results (103 total)" on filtered pages. |
sortable_by |
() |
Restrict sortable columns (empty = all sortable). |
empty_value_display |
"-" |
Display value for empty fields. |
verbose_name / verbose_name_plural |
None |
Override the model's display name. |
menu_section |
None |
Group the model under a section in the left menu. |
model_name_prefix |
None |
Prefix to disambiguate models when using several ORMs. |
Form page attributes¶
| Attribute | Default | Description |
|---|---|---|
fields |
() |
Subset/order of fields on add/change forms. |
fieldsets |
() |
Two-tuples grouping fields into form sections. |
exclude |
() |
Fields to exclude from the form. |
readonly_fields |
() |
Fields rendered non-editable. |
formfield_overrides |
{} |
Per-field widget overrides — see Form widgets. |
filter_horizontal / filter_vertical |
() |
Use a search-friendly two-box UI for M2M fields. |
radio_fields |
() |
Use radio buttons instead of a select for FK/choice fields. |
raw_id_fields |
() |
Use a plain input instead of a select for FK/M2M fields. |
save_as |
False |
Replace "Save and add another" with "Save as new". |
save_as_continue |
False |
Where "Save as new" redirects: the changelist by default, or the new object's change view when True. |
save_on_top |
False |
Show save buttons at the top of the form too. |
view_on_site |
None |
URL for a "View on site" link. |
inlines |
() |
Inline admin classes — see Inline admins. |
Actions¶
Define bulk actions with the @action decorator and list them in actions:
from fastadmin import TortoiseModelAdmin, action, register
from fastadmin import ActionResponseSchema, ActionResponseType
@register(Story)
class StoryAdmin(TortoiseModelAdmin):
actions = ("make_published",)
actions_on_top = False # actions bar at the top of the list page
actions_on_bottom = True # actions bar at the bottom
actions_selection_counter = True
@action(description="Mark selected stories as published")
async def make_published(self, objs: list) -> ActionResponseSchema | None:
for obj in objs:
obj.status = "published"
await obj.save()
return ActionResponseSchema(type=ActionResponseType.MESSAGE, data="Published!")
An action can return None, a MESSAGE response, or a DOWNLOAD_BASE64
response (data is base64 file content, file_name names the download).
Display fields¶
Add computed, read-only columns with the @display decorator and include
them in list_display:
from fastadmin import display
class EventAdmin(TortoiseModelAdmin):
list_display = ("id", "name", "is_published", "author")
@display
async def is_published(self, obj):
return obj.publish_date is not None
@display(sorter="user__username") # sortable by a related field
async def author(self, obj):
return (await obj.user).username
sorter=True sorts by the function name as a field; a string sorts by that
ORM expression.
Warning
String sorter expressions are supported only for Django and Tortoise ORM.
Save / delete hooks¶
Override these to customize persistence (always call super() unless you
replace the behavior entirely):
class EventAdmin(TortoiseModelAdmin):
async def save_model(self, id, payload: dict) -> dict | None:
payload["updated_by"] = self.user["id"] if self.user else None
return await super().save_model(id, payload)
async def delete_model(self, id) -> None:
await super().delete_model(id)
Other useful hooks:
orm_get_list(offset, limit, search, sort_by, filters)— low-level list query; override for custom querysets.serialize_obj(obj, list_view=False)— object → dict serialization.pre_generate_models_schema()— pre-generate the models schema (e.g. warm caches) before the configuration is served.get_export(...)— CSV/JSON export used by the export button (gate it withhas_export_permission).
Permissions and request context¶
See Authentication for
has_add/change/delete/export_permission and the self.request /
self.user context.
The full class reference lives in the API reference.