Каталог options
Каждая возможность Chassis — frozen dataclass. Не нужно наследовать
отдельный mixin для поиска, badges и export. Option-объекты кладутся в
ModelAdmin.options или назначаются на ChassisAdminSiteMixin.
Эта страница — полный каталог: зачем option, поля, значения по умолчанию, валидация и какой регион UI он управляет.
Как работает lookup
ChassisAdminMixin.get_chassis_option(option_class=...) возвращает
первый экземпляр этого типа в локальном списке options. Если в
локальном списке нет совпадения, берётся значение из
ChassisAdminMixin.options — [RowActionsOption()].
Следствия:
- Используется не больше одного экземпляра каждого типа. Несколько групп
FK-вкладок кладите внутрь одного
ForeignKeyTabsOption, а не тремя соседними option. - Если задать
options = [SearchOption(...)]и не указатьRowActionsOption, mixin всё равно подставит кнопку просмотра из class-level списка. - Чтобы скрыть row actions, передайте
RowActionsOption(actions=[]). Settings— неAdminOption. Его назначают вchassis_settings.
Атрибут options переименовывать нельзя.
Объединение AdminOption
Эти типы допустимы в ModelAdmin.options:
| Option | Регион страницы |
|---|---|
SearchOption | Fieldset поиска changelist |
FiltersOption | Fieldset фильтров changelist |
DateHierarchyOption | Иерархия дат changelist |
FieldTabsOption | Вкладки по choices |
ForeignKeyTabsOption | Вкладки по ForeignKey |
BadgeFieldsOption | Badge-колонки changelist |
PrettyJsonOption | JSON на change form / списке |
DecimalAmountOption | Целая сумма как Decimal |
RowActionsOption | Последняя колонка changelist |
ListActionsOption | Тулбар changelist |
ObjectActionsOption | Тулбар change form |
RelatedEntitiesOption | Связанные таблицы change form |
ImportOption | Флоу импорта и кнопка тулбара |
ExportOption | Флоу экспорта и кнопка тулбара |
Вложенные типы (RowActionOption, TableColumnOption, …) не входят в
AdminOption. Они живут внутри родительского option.
Site-level типы (Sidebar*, AdminPageGroupOption, PermissionOption)
назначаются на AdminSite, не в options.
Settings
Не option. Назначается в chassis_settings у ModelAdmin или AdminPage.
from django_chassis.options import Settings
chassis_settings = Settings(
search_collapsed=True, date_hierarchy_collapsed=True, filters_collapsed=True, allow_standard_add=True
)
| Поле | Тип | По умолчанию | Эффект |
|---|---|---|---|
search_collapsed | bool | True | Поиск изначально свёрнут |
date_hierarchy_collapsed | bool | True | Иерархия дат изначально свёрнута |
filters_collapsed | bool | True | Фильтры изначально свёрнуты |
allow_standard_add | bool | True | Кнопка «Добавить» Django в тулбаре changelist |
allow_standard_add=False заставляет has_add_permission() вернуть
False, поэтому стандартная кнопка «Добавить» исчезает. List actions и
кнопки import/export не затрагиваются.
SearchOption
Выносит Django search_fields в fieldset Chassis над таблицей. Mixin
записывает search_fields в instance, чтобы checks Django их видели.
from django_chassis.options import SearchOption
SearchOption(fields=['title', 'isbn', 'author__name'], fieldset_title='Поиск', placeholder='Название, ISBN или автор')
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
fields | list[str] | — | да |
fieldset_title | str или gettext lazy | _('Поиск') | нет |
placeholder | str или gettext lazy | '' | нет |
fields использует lookup Django (icontains по умолчанию, префикс ^,
точное =, полнотекст @ — как в стандартном Admin).
Без этой option у changelist нет fieldset поиска.
FiltersOption
Рисует select-фильтры Chassis в отдельном fieldset. fields становится
Django list_filter.
from django.contrib.admin import SimpleListFilter
from django_chassis.options import FiltersOption
FiltersOption(fields=['status', 'author', PublishedThisYearFilter], fieldset_title='Фильтры')
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
fields | list[Any] | — | да |
fieldset_title | локализованная строка | _('Фильтры') | нет |
Допустимы те же значения, что у Django list_filter: имена полей,
related lookup и подклассы SimpleListFilter.
Правый sidebar фильтров Django подавлен
({% block filters %}{% endblock %}). Фильтры живут в стеке контролов
Chassis над таблицей.
DateHierarchyOption
Включает Django date_hierarchy и оборачивает его в fieldset Chassis.
from django_chassis.options import DateHierarchyOption
DateHierarchyOption(field='published_at', fieldset_title='Даты')
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
field | str | — | да — имя DateField / DateTimeField |
fieldset_title | локализованная строка | _('Даты') | нет |
Mixin записывает date_hierarchy на instance для checks Django.
FieldTabsOption
Вкладки (или <select>), которые фильтруют changelist по полю
choices текущей модели. Каждая вкладка — ссылка с query-string;
«Все» сбрасывает фильтр.
from django_chassis.enums import TabDisplay
from django_chassis.options import FieldTabsOption
FieldTabsOption(
field='status', choices=Book.Status.choices, display=TabDisplay.BUTTONS, all_label='Все', fieldset_title='Статус'
)
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
field | str | — | да |
choices | list[tuple[Any, Any]] | — | да — пары (value, label) |
display | TabDisplay | TabDisplay.BUTTONS | нет |
all_label | локализованная строка | _('Все') | нет |
fieldset_title | локализованная строка | _('Tabs') | нет |
TabDisplay.BUTTONS — ряд ссылок. TabDisplay.SELECT — выпадающий
список с переходом при смене значения.
Для локального choices-поля — эта option. Для связанной модели —
ForeignKeyTabsOption.
ForeignKeyTabsOption
Одна или несколько групп вкладок, каждая привязана к ForeignKey текущей модели. Каждый связанный объект из queryset становится вкладкой.
from django_chassis.options import ForeignKeyTabGroupOption, ForeignKeyTabsOption
ForeignKeyTabsOption(
groups=[
ForeignKeyTabGroupOption(field='author', model=Author, label='Авторы', all_label='Все авторы'),
ForeignKeyTabGroupOption(field='publisher', model=Publisher, label='Издатели'),
],
display=TabDisplay.BUTTONS,
fieldset_title='Связи',
)
Короткий синтаксис одной группы
ForeignKeyTabsOption(field='author', model=Author)
эквивалентен одному ForeignKeyTabGroupOption в groups.
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
groups | list[ForeignKeyTabGroupOption] | [] | либо groups, либо field+model |
field | str или None | None | shortcut |
model | класс модели или None | None | shortcut |
display | TabDisplay | BUTTONS | нет |
all_label | локализованная строка | _('Все') | нет |
fieldset_title | локализованная строка | _('Tabs') | нет |
ForeignKeyTabGroupOption
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
field | имя FK на текущей модели | — | да |
model | класс связанной модели | — | да |
label | локализованная строка | '' | нет — заголовок группы |
all_label | локализованная строка | _('Все') | нет |
Два объекта ForeignKeyTabsOption повесить нельзя. Все группы — в
groups.
BadgeFieldsOption
Показывает названные колонки changelist цветными badge. Mixin подменяет
каждое перечисленное поле в list_display сгенерированным display-методом.
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}},
)
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
fields | list[str] | — | да |
colors | Mapping[str, Mapping[object, ButtonColor]] | {} | нет |
Без маппинга цвета используется тон badge по умолчанию. Ключи внутреннего маппинга — сырые значения поля (члены enum, строки, bool).
ButtonColor: primary, secondary, success, warning, danger,
info.
PrettyJsonOption
Для каждого JSON-поля создаёт read-only метод pretty_<field> и подсвечивает
значение через Pygments. Доменный ModelAdmin эти методы не объявляет.
from django_chassis.options import PrettyJsonOption
PrettyJsonOption(fields=['payload', 'metadata'])
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
fields | list[str] | — | да |
Исходное имя поля укажите в list_display / readonly_fields, если
нужна pretty-колонка. Mixin ставит метод в __init__.
DecimalAmountOption
Показывает целочисленные суммы в минимальных единицах как Decimal. На модели должны быть методы:
_get_fraction_number(...)convert_amount_to_decimal(...)
Если любого метода нет, option молча игнорируется (колонки не
переписываются). Если имя не IntegerField, при создании —
ImproperlyConfigured.
from django_chassis.options import DecimalAmountOption
DecimalAmountOption(fields=['amount', 'fee'])
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
fields | list[str] | — | да — уникальные имена IntegerField |
Повтор имён: ValueError('Chassis decimal amount field names must be unique.').
Сгенерированное имя в list-display: chassis_decimal_<field>. Сортировка
идёт по исходному integer.
RowActionsOption / RowActionOption
Последняя колонка changelist. Первая колонка не ссылка на change,
пока не задано chassis_link_first_column = True.
По умолчанию без аргументов: одна кнопка просмотра (Открыть,
fa-solid fa-arrow-right, ButtonColor.PRIMARY, отображение иконкой).
from django_chassis.enums import ButtonColor, RowActionDisplay, RowActionType
from django_chassis.options import RowActionOption, RowActionsOption
RowActionsOption(
actions=[
RowActionOption(
action_type=RowActionType.VIEW,
label='Открыть',
color=ButtonColor.PRIMARY,
icon_class='fa-solid fa-arrow-right',
display=RowActionDisplay.ICON,
),
RowActionOption(
action_type=RowActionType.CHANGE,
label='Изменить',
color=ButtonColor.SECONDARY,
icon_class='fa-solid fa-pen',
permission='change',
),
RowActionOption(
action_type=RowActionType.DELETE,
label='Удалить',
color=ButtonColor.DANGER,
icon_class='fa-solid fa-trash',
permission='delete',
),
RowActionOption(
action_type=RowActionType.HISTORY,
label='История',
color=ButtonColor.SECONDARY,
icon_class='fa-solid fa-clock-rotate-left',
),
]
)
RowActionsOption
| Поле | Тип | По умолчанию |
|---|---|---|
actions | list[RowActionOption] | одно действие VIEW |
RowActionOption
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
action_type | RowActionType | — | да — view, change, delete, history |
label | локализованная строка | — | да |
color | ButtonColor | — | да |
icon_class | класс Font Awesome | — | да |
display | RowActionDisplay | ICON | нет — icon или button |
permission | str или None | None | нет — при возможности выводится из типа |
Нет права — кнопка скрыта. Disabled-заглушки нет.
ListActionsOption / ListActionOption
Ссылки тулбара над changelist (рядом с «Добавить» и import/export). Резолвят имя URL Django; методы ModelAdmin не вызывают.
from django_chassis.options import ListActionOption, ListActionsOption
ListActionsOption(
actions=[
ListActionOption(
url_name='admin:catalog_book_changelist',
label='Все книги',
color=ButtonColor.PRIMARY,
icon_class='fa-solid fa-list',
permission='view',
condition_method='can_show_all_books',
)
]
)
ListActionOption
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
url_name | имя URL Django | — | да |
label | локализованная строка | — | да |
color | ButtonColor | PRIMARY | нет |
icon_class | класс Font Awesome | '' | нет |
permission | codename или None | None (в checks как view) | нет |
condition_method | имя метода или None | None | нет |
condition_method — @classmethod вида (cls, request) -> bool.
False убирает действие. Отсутствующее имя или не-classmethod —
ImproperlyConfigured при создании ModelAdmin.
Если права нет, в тулбаре может быть disabled-контрол (в отличие от row actions). Кнопки import/export тоже попадают сюда.
ObjectActionsOption
Имена методов ModelAdmin с декоратором @object_action. Они появляются в
тулбаре change form и получают маршрут:
{admin}/{app}/{model}/{object_id}/actions/{action_name}/
from django_chassis.options import ObjectActionsOption
ObjectActionsOption(actions=['publish', 'archive'])
| Поле | Тип | По умолчанию |
|---|---|---|
actions | list[str] | [] |
Повтор имён: ValueError('Chassis object action names must be unique.').
Имя без декоратора падает на валидации при создании.
Параметры декоратора — на странице Объектные действия.
RelatedEntitiesOption / RelatedEntityOption
Независимые таблицы с пагинацией под fieldsets change form
(after_field_sets). Каждая секция вызывает @classmethod с
@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='Книги',
get_items_method='get_books',
page_size=10,
table=TableOption(
columns=[
TableColumnOption(field='title', label='Название'),
TableColumnOption(field='isbn', label='ISBN'),
]
),
)
],
fieldset_title='Связанные',
collapsed=False,
pagination_state_ttl_seconds=30 * 60,
)
RelatedEntitiesOption
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
sections | list[RelatedEntityOption] | — | да |
fieldset_title | локализованная строка | 'Связанные сущности' | нет |
collapsed | bool | False | нет |
pagination_state_ttl_seconds | int | 1800 | нет — должно быть >= 1 |
RelatedEntityOption
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
slug | уникальный id секции | — | да |
title | локализованная строка | — | да |
get_items_method | имя метода | — | да |
table | TableOption | — | да |
page_size | int | 10 | нет — должно быть >= 1 |
collapsed | bool или None | None (наследует родителя) | нет |
Сигнатура провайдера: (cls, request, obj) -> QuerySet | Sequence.
Пагинация независима; состояние страницы живёт в query string / session
pagination_state_ttl_seconds секунд.
Семейство TableOption
Общий контракт таблицы для связанных сущностей, информационных страниц и блоков истории.
from django_chassis.options import TableActionOption, TableActionUrlKwargOption, TableColumnOption, TableOption
TableOption(
columns=[TableColumnOption(field='title', label='Название'), TableColumnOption(field='status', label='Статус')],
fieldset_title='Элементы',
empty_message='Нет строк.',
selection_field='id',
selection_disabled_field='locked',
selection_checked_field='selected',
actions=[
TableActionOption(
url_name='admin:catalog_book_change',
label='Открыть',
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
| Поле | Тип | По умолчанию |
|---|---|---|
columns | list[TableColumnOption] | обязательно |
fieldset_title | локализованная строка или None | None |
actions | list[TableActionOption] | [] |
selection_field | атрибут строки или None | None — значение checkbox |
selection_disabled_field | атрибут строки или None | None — truthy отключает |
selection_checked_field | атрибут строки или None | None — truthy отмечает заранее |
empty_message | локализованная строка | 'Нет данных для отображения.' |
TableColumnOption
| Поле | Тип | Обязательно |
|---|---|---|
field | dotted-путь на объекте строки | да |
label | заголовок колонки | да |
TableActionOption
| Поле | Тип | По умолчанию |
|---|---|---|
url_name | имя URL Django | обязательно |
label | локализованная строка | обязательно |
icon_class | класс Font Awesome | обязательно |
color | ButtonColor | PRIMARY |
display | RowActionDisplay | ICON |
object_field | атрибут строки для id объекта | 'id' |
object_url_kwarg | имя URL kwarg | 'object_id' |
permission | codename или None | None |
condition_method | имя метода или None | None |
url_kwargs | дополнительные TableActionUrlKwargOption | [] |
TableActionUrlKwargOption(name, value) добавляет постоянный
именованный аргумент в reverse(). Id объекта по-прежнему берётся из
object_field → object_url_kwarg. Если в url_name нет :, Chassis
добавляет имя текущего AdminSite.
permission=None разрешает действие. Отсутствующий condition_method даёт
TypeError в момент рендера.
ImportOption
Добавляет кнопку Import в тулбар и маршруты импорта (загрузка, preview, apply, история, скачивание).
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]
)
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
permission | непустая str | — | да |
fields | list[str] или None | None — все подходящие поля | нет |
formats | list[ImportFormat] или None | None — все ImportFormat | нет |
Валидация при создании:
- пустой
permission→ValueError formats=[]→ValueError- элементы не из
ImportFormat→TypeError
ImportFormat: JSON, XML.
Право должно существовать на модели (или как PermissionOption). Иначе
manage.py check сообщает chassis.E003.
ExportOption
Добавляет кнопку Export в тулбар и маршруты экспорта (форма, история, скачивание).
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,
)
| Поле | Тип | По умолчанию | Обязательно |
|---|---|---|---|
permission | непустая str | — | да |
fields | list[str] или None | None | нет |
formats | list[ExportFormat] или None | None — все члены enum | нет |
include_journals | bool | False | нет — история модели, если проект её даёт |
filter_fields | list[str] или None | None | нет — lookup Django на форме экспорта |
Валидация:
- пустой
permission→ValueError - пустые списки
formats/filter_fields→ValueError - неизвестные lookup в
filter_fields→chassis.E004на check
ExportFormat: JSON, XML, CSV, XLSX.
Файлы пишутся в STORAGES['media']. См. Import и export.
Site-level options
Эти типы не входят в ModelAdmin.options. Они живут на
ChassisAdminSiteMixin.
SidebarSectionOption
Раскрываемый раздел sidebar.
| Поле | Тип | По умолчанию |
|---|---|---|
slug | str | обязательно |
label | локализованная строка | обязательно |
icon_class | класс Font Awesome | обязательно |
items | list[SidebarModelItemOption | SidebarPageItemOption] | обязательно |
icon_color | SidebarIconColor | SLATE |
SidebarModelItemOption
| Поле | Тип | По умолчанию |
|---|---|---|
model | 'app_label.model' | обязательно — модель зарегистрирована на этом site |
label | локализованная строка или None | verbose name модели |
icon_class | класс Font Awesome | 'fa-solid fa-table-list' |
Скрыт, если у пользователя нет прав на модель.
SidebarPageItemOption
| Поле | Тип | По умолчанию |
|---|---|---|
page_slug | str | обязательно — страница в chassis_page_classes |
label | локализованная строка или None | label страницы |
icon_class | класс Font Awesome | '' |
Экземпляр страницы должен быть PermissionAdminPage. Personal и
superuser страницы нельзя класть в sidebar (ImproperlyConfigured).
SidebarLinkOption
Самостоятельная ссылка верхнего уровня (не внутри раздела).
| Поле | Тип | По умолчанию |
|---|---|---|
slug | str | обязательно |
label | локализованная строка | обязательно |
icon_class | класс Font Awesome | обязательно |
url_name | имя URL Django | обязательно |
Повтор slug и неизвестные model/page ссылки падают на checks сайта.
AdminPageGroupOption
Группирует кастомные страницы в dropdown navbar и/или секцию действий
dashboard. Тот же тип — AdminPage.navbar_group и
AdminPage.dashboard_group.
| Поле | Тип | По умолчанию |
|---|---|---|
slug | str | обязательно |
label | локализованная строка | обязательно |
icon_class | класс Font Awesome | обязательно |
order | int | 0 |
PersonalAdminPage в группу входить не может.
PermissionOption
Описывает право, которое Chassis регистрирует и создаёт после migrate.
from django_chassis.options import PermissionOption
PermissionOption(app_label='catalog', model='book', codename='export_book', name='Может экспортировать книгу')
| Поле | Тип | Ограничение |
|---|---|---|
app_label | str | идентификатор Python |
model | str | идентификатор в нижнем регистре |
codename | str | идентификатор |
name | локализованная строка | непустая |
Свойство value: '{app_label}.{codename}'.
На сайте: chassis_permission_options = (export_books,).
PermissionAdminPage.permission должен быть PermissionOption с
view_*.
Создание и checks
| Ошибка | Когда | Что |
|---|---|---|
ValueError / TypeError | __post_init__ option | пустой permission import/export, пустые списки, повтор имён действий, неположительный page size |
ImproperlyConfigured | __init__ ModelAdmin / site | нет classmethod условия, плохие decimal-поля, неверный контракт доступа страницы |
chassis.E002 | manage.py check | Django @admin.action без allowed_permissions |
chassis.E003 | manage.py check | permission действия / import / export не объявлен на модели |
chassis.E004 | manage.py check | неизвестный lookup в ExportOption.filter_fields |
См. также
- ModelAdmin — MRO, список
options, сопутствующие миксины - Changelist — как собирается страница списка
- Справочник API — компактные сигнатуры