Skip to main content

Options catalog

Added in 1.0.1

Every Chassis capability is a frozen dataclass. You do not subclass a mixin for search, another for badges, and another for export. You append option objects to ModelAdmin.options or assign site-level options on ChassisAdminSiteMixin.

This page is the full catalog: purpose, fields, defaults, validation, and which UI region each option drives.

How lookup works

ChassisAdminMixin.get_chassis_option(option_class=...) returns the first instance of that type on the local options list. If the local list has no match, it falls back to ChassisAdminMixin.options, which is [RowActionsOption()].

Consequences:

  • At most one instance of each option type is used. Put several FK tab groups inside one ForeignKeyTabsOption, not as three sibling options.
  • If you set options = [SearchOption(...)] and omit RowActionsOption, the mixin still injects the default view button from the class-level list.
  • To hide row actions, pass RowActionsOption(actions=[]).
  • Settings is not an AdminOption. Assign it to chassis_settings.

Do not rename the options attribute.

AdminOption union

These types are legal on ModelAdmin.options:

OptionPage region
SearchOptionChangelist search fieldset
FiltersOptionChangelist filter fieldset
DateHierarchyOptionChangelist date drill-down
FieldTabsOptionChangelist choice tabs
ForeignKeyTabsOptionChangelist FK tabs
BadgeFieldsOptionChangelist badge columns
PrettyJsonOptionChange form / list JSON
DecimalAmountOptionInteger money as Decimal
RowActionsOptionLast changelist column
ListActionsOptionChangelist toolbar
ObjectActionsOptionChange-form toolbar
RelatedEntitiesOptionChange-form related tables
ImportOptionImport flow + toolbar button
ExportOptionExport flow + toolbar button

Nested types (RowActionOption, TableColumnOption, …) are not AdminOption members. They live inside a parent option.

Site-level types (Sidebar*, AdminPageGroupOption, PermissionOption) are assigned on the AdminSite, not on options.


Settings

Not an option. Assigned to chassis_settings on a ModelAdmin or AdminPage.

from django_chassis.options import Settings

chassis_settings = Settings(
search_collapsed=True, date_hierarchy_collapsed=True, filters_collapsed=True, allow_standard_add=True
)
FieldTypeDefaultEffect
search_collapsedboolTrueSearch fieldset starts collapsed
date_hierarchy_collapsedboolTrueDate hierarchy starts collapsed
filters_collapsedboolTrueFilters fieldset starts collapsed
allow_standard_addboolTrueShow Django's Add button in the changelist toolbar

allow_standard_add=False makes has_add_permission() return False, so the standard Add button disappears. List actions and import/export buttons are unaffected.


SearchOption

Puts Django search_fields into a Chassis fieldset above the result table. The mixin writes search_fields onto the instance so Django's own checks still see them.

from django_chassis.options import SearchOption

SearchOption(fields=['title', 'isbn', 'author__name'], fieldset_title='Search', placeholder='Title, ISBN, or author')
FieldTypeDefaultRequired
fieldslist[str]yes
fieldset_titlestr or gettext lazy_('Поиск')no
placeholderstr or gettext lazy''no

fields uses Django search lookups (icontains by default, ^ prefix, = exact, @ full text — same as stock Admin).

Without this option the changelist has no search fieldset.


FiltersOption

Renders Chassis select-filters in their own fieldset. fields is assigned to Django list_filter.

from django.contrib.admin import SimpleListFilter
from django_chassis.options import FiltersOption

FiltersOption(fields=['status', 'author', PublishedThisYearFilter], fieldset_title='Filters')
FieldTypeDefaultRequired
fieldslist[Any]yes
fieldset_titlelocalized string_('Фильтры')no

Accepted values are the same as Django list_filter: field names, related lookups, and SimpleListFilter subclasses.

The stock Django right-hand filter sidebar is suppressed ({% block filters %}{% endblock %}). Filters live in the Chassis controls stack above the table.


DateHierarchyOption

Enables Django date_hierarchy and wraps it in a Chassis fieldset.

from django_chassis.options import DateHierarchyOption

DateHierarchyOption(field='published_at', fieldset_title='Dates')
FieldTypeDefaultRequired
fieldstryes — DateField / DateTimeField name
fieldset_titlelocalized string_('Даты')no

The mixin writes date_hierarchy on the instance for Django checks.


FieldTabsOption

Tabs (or a <select>) that filter the changelist by a choices field on the current model. Each tab is a query-string link; "All" clears the filter.

from django_chassis.enums import TabDisplay
from django_chassis.options import FieldTabsOption

FieldTabsOption(
field='status', choices=Book.Status.choices, display=TabDisplay.BUTTONS, all_label='All', fieldset_title='Status'
)
FieldTypeDefaultRequired
fieldstryes
choiceslist[tuple[Any, Any]]yes — (value, label) pairs
displayTabDisplayTabDisplay.BUTTONSno
all_labellocalized string_('Все')no
fieldset_titlelocalized string_('Tabs')no

TabDisplay.BUTTONS renders a row of links. TabDisplay.SELECT renders a dropdown that navigates on change.

Use this when the dimension is a local choices field. Use ForeignKeyTabsOption when the dimension is a related model.


ForeignKeyTabsOption

One or more tab groups, each bound to a ForeignKey on the current model. Every related object that appears in the queryset becomes a tab.

from django_chassis.options import ForeignKeyTabGroupOption, ForeignKeyTabsOption

ForeignKeyTabsOption(
groups=[
ForeignKeyTabGroupOption(field='author', model=Author, label='Authors', all_label='All authors'),
ForeignKeyTabGroupOption(field='publisher', model=Publisher, label='Publishers'),
],
display=TabDisplay.BUTTONS,
fieldset_title='Relations',
)

Single-group shortcut

ForeignKeyTabsOption(field='author', model=Author)

is equivalent to one ForeignKeyTabGroupOption in groups.

FieldTypeDefaultRequired
groupslist[ForeignKeyTabGroupOption][]one of groups or field+model
fieldstr or NoneNoneshortcut
modelmodel class or NoneNoneshortcut
displayTabDisplayBUTTONSno
all_labellocalized string_('Все')no
fieldset_titlelocalized string_('Tabs')no

ForeignKeyTabGroupOption

FieldTypeDefaultRequired
fieldFK field name on the current modelyes
modelrelated model classyes
labellocalized string''no — group heading
all_labellocalized string_('Все')no

You cannot attach two ForeignKeyTabsOption objects. Put every group in groups.


BadgeFieldsOption

Renders named changelist columns as colored badges. The mixin replaces each listed field in list_display with a generated display method.

from django_chassis.enums import ButtonColor
from django_chassis.options import BadgeFieldsOption

BadgeFieldsOption(
fields=['status', 'kind'],
colors={'status': {'active': ButtonColor.SUCCESS, 'draft': ButtonColor.SECONDARY, 'archived': ButtonColor.WARNING}},
)
FieldTypeDefaultRequired
fieldslist[str]yes
colorsMapping[str, Mapping[object, ButtonColor]]{}no

A missing color mapping uses the default badge tone. Keys of the inner mapping are the raw field values (enum members, strings, booleans).

ButtonColor: primary, secondary, success, warning, danger, info.


PrettyJsonOption

Builds a read-only pretty_<field> display method for each JSON field and highlights it with Pygments. Domain ModelAdmins do not declare those methods by hand.

from django_chassis.options import PrettyJsonOption

PrettyJsonOption(fields=['payload', 'metadata'])
FieldTypeDefaultRequired
fieldslist[str]yes

Put the original field name in list_display / readonly_fields if you want the pretty column on the changelist or change form. The mixin installs the method at __init__ time.


DecimalAmountOption

Displays integer minor-unit amounts as Decimal using two methods on the model:

  • _get_fraction_number(...)
  • convert_amount_to_decimal(...)

If either method is missing, the option is silently ignored (no column rewrite). If a listed name is not an IntegerField, construction raises ImproperlyConfigured.

from django_chassis.options import DecimalAmountOption

DecimalAmountOption(fields=['amount', 'fee'])
FieldTypeDefaultRequired
fieldslist[str]yes — unique integer field names

Duplicate names raise ValueError('Chassis decimal amount field names must be unique.').

Generated list-display name: chassis_decimal_<field>. Sorting still uses the underlying integer.


RowActionsOption / RowActionOption

Last changelist column. The first column is not a change-link unless you set chassis_link_first_column = True.

Default without arguments: one view button (Открыть / Open, fa-solid fa-arrow-right, ButtonColor.PRIMARY, icon display).

from django_chassis.enums import ButtonColor, RowActionDisplay, RowActionType
from django_chassis.options import RowActionOption, RowActionsOption

RowActionsOption(
actions=[
RowActionOption(
action_type=RowActionType.VIEW,
label='Open',
color=ButtonColor.PRIMARY,
icon_class='fa-solid fa-arrow-right',
display=RowActionDisplay.ICON,
),
RowActionOption(
action_type=RowActionType.CHANGE,
label='Edit',
color=ButtonColor.SECONDARY,
icon_class='fa-solid fa-pen',
permission='change',
),
RowActionOption(
action_type=RowActionType.DELETE,
label='Delete',
color=ButtonColor.DANGER,
icon_class='fa-solid fa-trash',
permission='delete',
),
RowActionOption(
action_type=RowActionType.HISTORY,
label='History',
color=ButtonColor.SECONDARY,
icon_class='fa-solid fa-clock-rotate-left',
),
]
)

RowActionsOption

FieldTypeDefault
actionslist[RowActionOption]one VIEW action

RowActionOption

FieldTypeDefaultRequired
action_typeRowActionTypeyes — view, change, delete, history
labellocalized stringyes
colorButtonColoryes
icon_classFont Awesome classyes
displayRowActionDisplayICONno — icon or button
permissionstr or NoneNoneno — inferred from type when possible

A failed permission hides the button. There is no disabled placeholder.


ListActionsOption / ListActionOption

Toolbar links above the changelist (next to Add and import/export). They resolve a Django URL name; they do not run ModelAdmin methods.

from django_chassis.options import ListActionOption, ListActionsOption

ListActionsOption(
actions=[
ListActionOption(
url_name='admin:catalog_book_changelist',
label='All books',
color=ButtonColor.PRIMARY,
icon_class='fa-solid fa-list',
permission='view',
condition_method='can_show_all_books',
)
]
)

ListActionOption

FieldTypeDefaultRequired
url_nameDjango URL nameyes
labellocalized stringyes
colorButtonColorPRIMARYno
icon_classFont Awesome class''no
permissioncodename or NoneNone (treated as view in checks)no
condition_methodmethod name or NoneNoneno

condition_method must be a @classmethod shaped (cls, request) -> bool. False omits the action. A missing or non-classmethod name fails at ModelAdmin construction (ImproperlyConfigured).

If the permission is missing, the toolbar may show a disabled control (unlike row actions). Import/export buttons are injected here as well when those options are present.


ObjectActionsOption

Names of ModelAdmin methods decorated with @object_action. They appear on the change form toolbar and get a route:

{admin}/{app}/{model}/{object_id}/actions/{action_name}/

from django_chassis.options import ObjectActionsOption

ObjectActionsOption(actions=['publish', 'archive'])
FieldTypeDefault
actionslist[str][]

Duplicate names raise ValueError('Chassis object action names must be unique.'). An undecorated name fails validation at construction.

Decorator parameters are documented on Object actions.


RelatedEntitiesOption / RelatedEntityOption

Independent paginated tables below the fieldsets on the change form (after_field_sets). Each section calls a @classmethod marked @chassis_related_items.

from django_chassis.decorators import chassis_related_items
from django_chassis.options import RelatedEntitiesOption, RelatedEntityOption, TableColumnOption, TableOption

RelatedEntitiesOption(
sections=[
RelatedEntityOption(
slug='books',
title='Books',
get_items_method='get_books',
page_size=10,
table=TableOption(
columns=[TableColumnOption(field='title', label='Title'), TableColumnOption(field='isbn', label='ISBN')]
),
)
],
fieldset_title='Related',
collapsed=False,
pagination_state_ttl_seconds=30 * 60,
)

RelatedEntitiesOption

FieldTypeDefaultRequired
sectionslist[RelatedEntityOption]yes
fieldset_titlelocalized string'Связанные сущности'no
collapsedboolFalseno
pagination_state_ttl_secondsint1800no — must be >= 1

RelatedEntityOption

FieldTypeDefaultRequired
slugunique section idyes
titlelocalized stringyes
get_items_methodmethod nameyes
tableTableOptionyes
page_sizeint10no — must be >= 1
collapsedbool or NoneNone (inherit parent)no

Provider signature: (cls, request, obj) -> QuerySet | Sequence. Pagination is per section; page state lives in the query string / session for pagination_state_ttl_seconds.


TableOption family

Reusable table contract for related entities, information pages, and history-style blocks.

from django_chassis.options import TableActionOption, TableActionUrlKwargOption, TableColumnOption, TableOption

TableOption(
columns=[TableColumnOption(field='title', label='Title'), TableColumnOption(field='status', label='Status')],
fieldset_title='Items',
empty_message='No rows.',
selection_field='id',
selection_disabled_field='locked',
selection_checked_field='selected',
actions=[
TableActionOption(
url_name='admin:catalog_book_change',
label='Open',
icon_class='fa-solid fa-arrow-right',
object_field='id',
object_url_kwarg='object_id',
permission='view',
url_kwargs=[TableActionUrlKwargOption(name='extra', value='kind')],
)
],
)

TableOption

FieldTypeDefault
columnslist[TableColumnOption]required
fieldset_titlelocalized string or NoneNone
actionslist[TableActionOption][]
selection_fieldrow attribute or NoneNone — checkbox value
selection_disabled_fieldrow attribute or NoneNone — truthy disables
selection_checked_fieldrow attribute or NoneNone — truthy pre-checks
empty_messagelocalized string'Нет данных для отображения.'

TableColumnOption

FieldTypeRequired
fielddotted path on the rowyes
labelcolumn headeryes

TableActionOption

FieldTypeDefault
url_nameDjango URL namerequired
labellocalized stringrequired
icon_classFont Awesome classrequired
colorButtonColorPRIMARY
displayRowActionDisplayICON
object_fieldrow attribute for the object id'id'
object_url_kwargURL kwarg name'object_id'
permissioncodename or NoneNone
condition_methodmethod name or NoneNone
url_kwargsextra TableActionUrlKwargOption[]

TableActionUrlKwargOption(name, value) adds a constant keyword argument to reverse(). The object id still comes from object_fieldobject_url_kwarg. If url_name has no :, Chassis prefixes the current AdminSite name.

permission=None allows the action. A named condition_method that is missing raises TypeError at render time.


ImportOption

Adds an Import toolbar button and the import routes (upload, preview, apply, history, download).

from django_chassis.enums import ImportFormat
from django_chassis.options import ImportOption

ImportOption(
permission='import_book', fields=['title', 'isbn', 'status'], formats=[ImportFormat.JSON, ImportFormat.XML]
)
FieldTypeDefaultRequired
permissionnon-blank stryes
fieldslist[str] or NoneNone — all eligible fieldsno
formatslist[ImportFormat] or NoneNone — every ImportFormatno

Validation at construction:

  • blank permissionValueError
  • formats=[]ValueError
  • non-ImportFormat members → TypeError

ImportFormat: JSON, XML.

The permission must exist on the model (or as a PermissionOption). manage.py check reports chassis.E003 otherwise.


ExportOption

Adds an Export toolbar button and export routes (form, history, download).

from django_chassis.enums import ExportFormat
from django_chassis.options import ExportOption

ExportOption(
permission='export_book',
fields=['title', 'isbn', 'status'],
formats=[ExportFormat.JSON, ExportFormat.CSV, ExportFormat.XLSX],
filter_fields=['status', 'author'],
include_journals=False,
)
FieldTypeDefaultRequired
permissionnon-blank stryes
fieldslist[str] or NoneNoneno
formatslist[ExportFormat] or NoneNone — all enum membersno
include_journalsboolFalseno — include model history when the project provides it
filter_fieldslist[str] or NoneNoneno — Django lookups on the export form

Validation:

  • blank permissionValueError
  • empty formats / filter_fields lists → ValueError
  • unknown filter_fields lookups → chassis.E004 at check time

ExportFormat: JSON, XML, CSV, XLSX.

Files go to STORAGES['media']. See Import and export.


Site-level options

These are not in ModelAdmin.options. They live on ChassisAdminSiteMixin.

SidebarSectionOption

Collapsible sidebar group.

FieldTypeDefault
slugstrrequired
labellocalized stringrequired
icon_classFont Awesome classrequired
itemslist[SidebarModelItemOption | SidebarPageItemOption]required
icon_colorSidebarIconColorSLATE

SidebarModelItemOption

FieldTypeDefault
model'app_label.model'required — must be registered on this site
labellocalized string or Nonemodel verbose name
icon_classFont Awesome class'fa-solid fa-table-list'

Hidden when the user lacks model permissions.

SidebarPageItemOption

FieldTypeDefault
page_slugstrrequired — page in chassis_page_classes
labellocalized string or Nonepage label
icon_classFont Awesome class''

The page instance must be a PermissionAdminPage. Personal and superuser pages cannot be sidebar children (ImproperlyConfigured).

SidebarLinkOption

Standalone top-level link (not inside a section).

FieldTypeDefault
slugstrrequired
labellocalized stringrequired
icon_classFont Awesome classrequired
url_nameDjango URL namerequired

Duplicate slugs and unknown model/page references fail site checks.

AdminPageGroupOption

Groups custom pages into a navbar dropdown and/or a dashboard actions section. Reused as AdminPage.navbar_group and AdminPage.dashboard_group.

FieldTypeDefault
slugstrrequired
labellocalized stringrequired
icon_classFont Awesome classrequired
orderint0

PersonalAdminPage cannot join a group.

PermissionOption

Declares a permission that Chassis registers and creates after migrate.

from django_chassis.options import PermissionOption

PermissionOption(app_label='catalog', model='book', codename='export_book', name='Can export book')
FieldTypeConstraint
app_labelstrPython identifier
modelstrlowercase identifier
codenamestridentifier
namelocalized stringnon-empty

value property: '{app_label}.{codename}'.

Assign on the site as chassis_permission_options = (export_books,). PermissionAdminPage.permission must be a view_* PermissionOption.


Construction and checks

FailureWhenWhat
ValueError / TypeErroroption __post_init__blank import/export permission, empty lists, duplicate action names, non-positive page size
ImproperlyConfiguredModelAdmin / site __init__missing condition classmethods, bad decimal fields, invalid page access contracts
chassis.E002manage.py checkDjango @admin.action without allowed_permissions
chassis.E003manage.py checkaction / import / export permission not declared on the model
chassis.E004manage.py checkunknown ExportOption.filter_fields lookup

See also