ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Baserow 插件开发实战:从零实现一个自定义 Application Type(以 TextFile 为例)

Baserow 插件开发实战:从零实现一个自定义 Application Type(以 TextFile 为例) Baserow 插件开发实战从零实现一个自定义 Application Type以 TextFile 为例【免费下载链接】baserowBuild databases, automations, apps agents with AI — no code. Open source platform available on cloud and self-hosted. GDPR, HIPAA, SOC 2 compliant. Best Airtable alternative.项目地址: https://gitcode.com/GitHub_Trending/ba/baserow本文以 Baserow 官方插件文档 docs/plugins/application-type.md 为主线完整讲解如何通过插件为一个 workspace 添加一种全新的「应用类型」在后端注册ApplicationType与自定义Application子模型、执行迁移、通过create_applicationAPI 验证再在前端注册对应的ApplicationType类让侧边栏的 Create new 按钮能创建并选中这种应用。读完本文你能掌握 Baserow 前后端双注册机制、Application模型的继承约定、ApplicationType可覆写钩子以及创建应用的完整服务端调用链。1. Application 是什么workspace 下的应用抽象在 Baserow 中「Application应用」是一种可以添加到 workspace 的顶层抽象——数据库database、表单等都以应用的形式存在于 workspace 中。插件作者可以注册自己独有的应用类型例如一个「文本文件」应用让用户通过 Create new 按钮在自己的 workspace 里创建其实例。从源码结构看这一抽象由两个核心部分支撑后端模型基类Application见 backend/src/baserow/core/models.py字段workspace外键可空、name160 字符、order排序、content_type多态内容类型用于区分不同的应用子类、installed_from_template关联安装来源模板混入能力HierarchicalModelMixin层级结构、TrashableModelMixin回收站、CreatedAndUpdatedOnMixin时间戳、OrderableMixin排序、PolymorphicContentTypeMixin多态、WithRegistry与注册表联动Application.get_type_registry()直接返回全局的application_type_registry这是模型与类型注册表之间的桥梁。后端类型基类ApplicationType见 backend/src/baserow/core/registries.py文档明确说明它「必须由插件扩展以实现定制」每个应用类型必须有一个继承Application的独立模型这样用户才能为每个创建的应用实例保存各自的自定义属性。ApplicationType通过ApplicationTypeRegistry注册注册表类定义在 registries.py全局实例application_type_registry定义在同文件末尾 L1443注册后用户即可在应用中创建该类型的实例并可挂载 API 路由。2. 后端实现模型、类型与注册以下以官方文档中的text_file应用为例完整给出后端三步改动。前置条件你已按 docs/plugins/boilerplate.md 准备了插件骨架注意该文档注明模板仅适用于 Baserow 2.0.6 及更早版本新插件应参照官方独立的 plugin-boilerplate 仓库本文以当前仓库的注册 API 为准。2.1 定义应用的模型models.py模型决定了每个「文本文件」实例在数据库中的表结构。即使暂时没有自定义属性也必须有一个继承Application的模型类# plugins/my_baserow_plugin/backend/src/my_baserow_plugin/models.py from baserow.core.models import Application class TextFile(Application): pass如文档所述也可以在TextFile上添加字段来保存每个文本文件实例独有的属性——每次用户创建一个新应用时对应的模型实例会自动创建。2.2 定义并声明 ApplicationTypeapplication_types.py# plugins/my_baserow_plugin/backend/src/my_baserow_plugin/application_types.py from baserow.core.registries import ApplicationType from .models import TextFile class TextFileApplicationType(ApplicationType): type text_file model_class TextFile两个类属性的含义属性含义源码依据type应用类型的唯一标识create_applicationAPI 用这个名字查找类型CoreHandler.create_application通过application_type_registry.get(type_name)解析见 handler.pymodel_class该类型对应的Application子类创建实例时实际实例化的模型ApplicationType.create_application中model self.model_class见 registries.py2.3 在插件配置中完成注册config.py注册发生在 Django 应用配置的ready()钩子中这是插件「被 Baserow 看见」的关键时刻# plugins/my_baserow_plugin/backend/src/my_baserow_plugin/config.py from django.apps import AppConfig from baserow.core.registries import plugin_registry, application_type_registry class PluginNameConfig(AppConfig): name my_baserow_plugin def ready(self): from .plugins import PluginNamePlugin from .application_types import TextFileApplicationType plugin_registry.register(PluginNamePlugin()) application_type_registry.register(TextFileApplicationType())注册完成后Baserow 后端即知道存在一个名为text_file的额外应用类型。插件机制的总览可参考 docs/plugins/creation.md。2.4 应用数据库迁移由于TextFile是一个新的 Django 模型需要生成并应用迁移。在 backend 容器内执行$ baserow makemigrations my_baserow_plugin $ baserow migrate2.5 注册之后框架替你做了什么理解注册后的运行时行为能让插件设计更稳妥。结合 registries.py 与 handler.py有几点值得注意ApplicationType的关键类属性均有源码默认值可按需覆写属性默认值作用instance_serializer_classNone序列化应用实例模型所用的 serializersupports_actionsTrue该应用是否支持自动化动作supports_snapshotsTrue是否支持快照历史版本supports_integrationsFalse是否支持集成可用supports_integration_type做更细粒度的判断supports_user_sourcesFalse是否支持用户数据源import_application_priority0在import_applications_to_workspace中的导入顺序值越小越先导入data_provider_type_registryNone该类型适用的数据提供者注册表文档注明子类必须设置它才能正确工作运行时公式校验可覆写的生命周期钩子prepare_value_for_db创建/更新前修改入库值更新时instance参数不为空、after_create、after_update、pre_delete、init_applicationinit_with_dataTrue创建时用来注入初始数据、export_safe_transaction_context导出时安全的事务上下文默认抛NotImplementedError需要自行实现等。创建应用的完整调用链create_applicationAPI 最终进入CoreHandler.create_applicationbackend/src/baserow/core/handler.py其流程为用CreateApplicationsWorkspaceOperationType校验用户对目标 workspace 的权限application_type_registry.get(type_name)按类型名取出ApplicationType实例extract_allowed(kwargs, default_create_allowed_fields application_type.allowed_fields)过滤出允许创建的字段——也就是说插件类型可以通过allowed_fields声明接受哪些额外参数调用application_type.prepare_value_for_db(...)做入库前变换application_type.create_application(user, workspace, init_with_data..., **prepared_values)创建实例——基类实现中会先model.get_last_order(workspace)取当前 workspace 的最大排序值加一再model.objects.create(workspace..., order..., **kwargs)落库依次触发after_create钩子并发送application_created信号。2.6 验证调用 create_application API迁移完成后文档建议直接调用create_application端点创建一个text_file类型的应用来验证后端。请求细节可参考仓库内的 REST API 文档。只要该调用成功返回新应用说明后端注册链路已经打通可以进入前端部分。如需查看ApplicationType的全部可覆写项文档指引你检查backend/src/baserow/core/registries.py中的ApplicationType类即上文 registries.py 一节本文第 2.5 小节已按当前仓库源码整理了其主要属性与钩子。3. Web 前端实现让 Create new 按钮认识你的应用由于 Baserow 的后端与 web-frontend 是两个独立应用、仅通过 REST API 通信前端并不知道text_file应用类型的存在。前端同样需要一次注册方式与后端对称。3.1 前端 ApplicationType 类applicationTypes.js// plugins/my_baserow_plugin/web-frontend/applicationTypes.js import { ApplicationType } from baserow/modules/core/applicationTypes export class TextFileApplicationType extends ApplicationType { static getType() { return text_file } getIconClass() { return iconoir-file-alt } getName() { return Text file } select(application) { console.log(text file selected with id from dashboard ${application.id}) } }前端基类 web-frontend/modules/core/applicationTypes.js 对这三个方法有硬性约束构造函数L122-L136会调用getType()、getIconClass()并检查name任一为null都会直接抛出Error。其中static getType()返回的字符串必须与后端ApplicationType.type完全一致text_file这是前后端类型对齐的契约getIconClass()返回图标后缀最终渲染为iconoir-file-alt这样的 CSS 类名getName()是显示名称select(application, context)在用户从侧边栏/dashboard 选中该应用时被调用基类默认返回true见 L175-L177示例中先只打印日志占位。3.2 插件入口注册plugin.js// plugins/my_baserow_plugin/web-frontend/plugin.js import { PluginNamePlugin } from my-baserow-plugin/plugins import { TextFileApplicationType } from my-baserow-plugin/applicationTypes export default (context) { const { app } context app.$registry.register(plugin, new PluginNamePlugin(context)) app.$registry.register(application, new TextFileApplicationType(context)) }注意前端注册名是application与后端ApplicationTypeRegistry.name application见 registries.py相对应两侧通过 registry 名称和类型字符串建立联系。3.3 前端基类提供了哪些可覆写点文档提示当前状态下点击 Create new 创建的文本文件「什么都不会发生」因为还需要覆写更多方法。从 applicationTypes.js 基类看可用于扩展的关键方法包括方法默认行为典型用途getDescription()返回null在 Create new 上下文中显示的类型描述getDefaultName()回退为getName()新应用的默认名称getApplicationFormComponent()返回ApplicationForm仅含名称字段创建时需要的自定义表单组件getSidebarComponent()返回null侧边栏中代表该应用实例、允许用户选中的组件getTemplatesPageComponent()/getTemplatePage()返回null模板弹窗中应用被选中时的预览组件与 propsgetDependents()/getDependentsName()空列表 /[null, null]删除或列表时展示应用子项如「1 个 table」populate(application)原样返回应用对象从后端获取后填充实例独有属性select(application, context)返回true选中应用后的行为如跳转路由delete(application, context)无操作删除应用时的附加处理如重定向isVisible(application)/canBeCreated()均返回true控制应用是否出现在侧边栏/是否可被创建getOrder()返回50类型排序serialize()返回{type, iconClass, name, routeName, hasSidebarComponent}前端类型自身的序列化输出见 L141-L149文档给出的下一步建议是创建一个新路由并在新建路由名通过getRouteName方法提供给类型这样用户点击侧边栏的文本文件时就会导航到该路由serialize()输出的routeName字段正是这一导航机制的载体见上文链接。完整可覆写项同样建议对照 web-frontend/modules/core/applicationTypes.js 源码确认。4. 关键要点清单前后端双注册后端application_type_registry.register(...)config.py 示例与前端app.$registry.register(application, ...)缺一不可type字符串text_file是两侧的对齐契约每个类型必须有独立模型model_class指向的Application子类是保存实例级自定义属性的载体也是create_application时objects.create的实际目标registries.py迁移不可省略新模型必须baserow makemigrations plugin_app baserow migrate后才能被创建用 API 验证后端通过create_application端点创建text_file类型实例参考 REST API 文档钩子是定制入口后端用prepare_value_for_db/after_create/init_application/allowed_fields控制创建流程handler.py前端用select/getSidebarComponent/getApplicationFormComponent/路由方法控制交互能力开关要显式考虑supports_actions、supports_snapshots、supports_integrations、supports_user_sources、import_application_priority决定该应用与自动化、快照、集成、模板导入的兼容程度默认值均定义在 ApplicationType 基类。【免费下载链接】baserowBuild databases, automations, apps agents with AI — no code. Open source platform available on cloud and self-hosted. GDPR, HIPAA, SOC 2 compliant. Best Airtable alternative.项目地址: https://gitcode.com/GitHub_Trending/ba/baserow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表