Студия: поля модели из интерфейса¶
Администратор настроек добавляет к модели своё поле без кода — в режиме студии на форме модели. Поле становится обычной колонкой таблицы и обычным полем модели: его видят список, форма, фильтры, экспорт в Excel и API /auto.
Установка¶
Студия по умолчанию выключена: ставит её администратор на странице Настройки → Прочее → Приложения (/apps), без рестарта. Это отключаемый сервис ("core": False): установка запускает его startup — поля вешаются на модели, схемы и роуты автокруда пересобираются; удаление зовёт shutdown — поля снимаются с моделей, роуты /studio/* вырезаются. Колонки, строки studio_fields и настройки форм остаются в базе: повторная установка вернёт всё как было. Пока студия не установлена, фронт настройки форм не грузит и не применяет (зоны «Дополнительно» и обязательности из настроек нет).
Режим студии¶
Иконка в шапке (как Studio в Odoo) появляется, когда открыта форма модели, модуль установлен и пользователь — администратор настроек. В режиме студии зона «Дополнительно» формы становится редактором сетки, а справа под шапкой открывается панель — форма сужается на её ширину, так что панель не закрывает ни разметку, ни зону «сбоку», ни шапку.
Над сеткой зоны — её место (снизу / сбоку / вкладка) и размер сетки (колонки × строки, пустые строки — сколько понадобится). Пустые клетки видны пунктиром; клетка под курсором подсвечивается фиолетовым, если примет поле, и красным, если нет. Подробности — в разделе «Поля формы» настроек видов.
- Добавить — новые поля по типам и существующие поля модели; перетаскиваются в клетку зоны, поля зоны — тоже перетаскиванием (на другое поле — обмен местами), крестик убирает поле с формы. Новое поле создаётся сразу: имя
x_<тип>_<номер>, подпись «Новое поле»; «Ссылка на запись» сначала спросит модель. - Свойства — выбранное поле: подпись и варианты (у полей студии), техническое имя, тип, ширина и высота в клетках, у строки — «Ссылка» (иконка перехода на сайт в новой вкладке, вид
charUrlхранится в клетке зоны), «Обязательное», «Убрать с формы», «Удалить поле». - Поля формы — обязательность полей разметки; саму разметку студия не трогает. Обязательное по модели включено всегда.
Каждое действие сохраняется сразу. Фронт — модуль fara_studio, к ядру подключается крючками: registerHeaderAction (иконка и прогрев настроек форм), registerExtension('*', …, 'provide:FormFields') (поля зоны «Дополнительно» в запрос записи и обязательные поля) и registerExtension('*', …, 'wrap:Form') (обёртка разметки каждой формы: ставит зону под разметкой, сбоку или вкладкой, сообщает шапке об открытой форме, в режиме студии держит редактор, перетаскивание и панель). Зона, сетка и настройки форм — в fara_studio (zone/, useFormSettings.ts, formSettingsApi.ts); ядро о них не знает. Редактор живёт в обёртке, а не в зоне: зону во вкладке Mantine прячет через Activity, и вместе с её эффектами пропадали бы иконка и панель. Без модуля поведение ядра не меняется.
Как устроено¶
- Описание — таблица
studio_fields(модульbackend/base/system/studio): модель, техническое имя, подпись, тип, варианты выбора, связанная модель. Источник истины — база: дамп базы содержит и настройку. - Настройки форм — таблица
form_settings(models/form_setting.py) тоже принадлежит студии: обязательные поля и зона «Дополнительно» (место, сетка, клетки). Читают все пользователи, меняетsystem_admin; права создаются при установке студии. - Старт. Установленный сервис
studioзапускается после чтения флагов установки и до автокруда (sequence5): вешает поля на модели (DotModel.add_fields+ аннотация типа для схем API) и добавляет недостающие колонки штатным DDL-синком. Схемы и роуты/autoстроятся уже с ними. - Сразу, без перезапуска.
POST /studio/fields: строка, поле на модели,ALTER TABLE … ADD COLUMN, поле в «Дополнительно» общих настроек формы, пересборка схем и авто-роутов этого воркера (около 2 с), событиеstudio_changedв шину — остальные воркеры и крон приводят свои модели к таблице (StudioApp.sync; на событие студия подписывается сама вstartupчерезenv.apps.bus.subscribe). - Правка.
PATCH /studio/fields/{id}— подпись и варианты выбора; применяются на месте, без пересборки схем, остальным воркерам — то же событие. - Удаление.
DELETE /studio/fields/{id}: строка, поле с модели, имя вычищается из настроек формы. Колонка и данные в базе остаются: поле с тем же именем и типом, созданное заново, получит прежние значения. Удаление колонки отключено намеренно (закомментировано в роутере и сервисе базы).
Правила¶
- Имя:
x_плюс латиница, цифры и подчёркивание (x_segment). Префикс отличает поле студии от полей ядра и не даст им пересечься. - Тип и имя после создания не меняются — поле создаётся заново. Поскольку колонка после удаления остаётся, новое поле с прежним именем должно быть того же типа.
- Типы: строка, текст, целое, дробное, флажок, дата, дата и время, выбор из списка (пары «значение — подпись»), ссылка на запись (модель из реестра). Many2many, файлы и related-поля — нет.
- Подпись —
stringполя; форма и меню колонок показывают её там, где у поля нет метки в разметке.
Код¶
models/studio_field.py — модель и проверки (STUDIO_FIELD_*), build() собирает поле dotorm; app.py — refresh (поля к таблице, подпись и варианты на месте), rebuild (схемы и роуты через DotormCrudAutoService.rebuild), sync, publish, show_on_form, forget; routers/studio.py — четыре ручки. Ядро: DotModel.remove_fields, DotormDatabasesPostgresService.sync_tables. Фронт: fara_studio — StudioToggle (иконка), StudioFormShell (обёртка формы, DndContext, панель), StudioZone (редактор сетки), StudioPanel, useStudioEditor (черновик и запись настроек), api.ts.