关于 frappe-syntax-doctypes
面向 Frappe 应用开发者的 DocType JSON 设计参考,涵盖数据模型、表单字段、命名规则及常见 DocType 类型,帮助在编写控制器逻辑前规划结构。
主要功能
- 01DocType 顶层属性参考
- 02常用字段类型与属性
- 03命名规则和模式示例
- 04子表、单例及树形设计
- 05自定义字段与属性设置
- 06虚拟 DocType 和类型标注
适用场景
- 01规划应用的数据结构
- 02配置字段和表单行为
- 03设计命名与子表关系
- 04为现有 DocType 添加自定义字段
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ impertio-studio/ frappe_claude_skill_package --skill frappe-syntax-doctypes安装后在 Claude Code 中输入/frappe-syntax-doctypes确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/.gitkeepanti-patterns.mdcustomization.mddata-masking.mdexamples.mdfieldtypes.mdnaming.mdtype-stubs.md详细介绍
DocType JSON 设计
DocType 是每个 Frappe 应用的基础。DocType 同时定义数据模型(数据库架构)和视图(表单布局)。务必先设计 DocType,再编写任何控制器逻辑。
快速参考
DocType JSON 顶层属性
| 属性 | 类型 | 用途 |
|---|---|---|
name | str | DocType 标识符(单数形式,例如 "Sales Invoice") |
module | str | 此 DocType 所属的应用模块 |
is_submittable | bool | 启用 Draft -> Submitted -> Cancelled 工作流 |
is_tree | bool | 启用 NestedSet 层级结构(lft/rgt 列) |
is_virtual | bool | 无数据库表;数据来自自定义后端 |
issingle | bool | 单实例设置文档 |
istable | bool | 子表 DocType(嵌入父文档中) |
is_calendar_and_gantt | bool | 启用日历/甘特图视图 |
track_changes | bool | 每次保存时存储版本历史 |
track_seen | bool | 跟踪哪些用户查看过此文档 |
track_views | bool | 统计文档总浏览次数 |
allow_rename | bool | 允许创建后重命名 |
allow_copy | bool | 启用“复制”操作 |
allow_import | bool | 为此 DocType 启用数据导入 |
naming_rule | str | 命名方法选择器(参见“命名”部分) |
autoname | str | 命名模式字符串 |
title_field | str | 用作显示标题的字段 |
search_fields | str | 用于搜索结果的逗号分隔字段 |
show_title_field_in_link | bool | 在 Link 字段中显示标题而非名称 |
image_field | str | 包含头像图片的字段 |
sort_field | str | 默认排序列 |
sort_order | str | "ASC" 或 "DESC" |
default_print_format | str | Print Format 名称 |
max_attachments | int | 附件数量上限 |
常见字段类型(快速查询)
| 字段类型 | 存储内容 | 数据库列 |
|---|---|---|
| Data | 最多 140 个字符的文本 | VARCHAR(140) |
| Link | 对另一个 DocType 的引用 | VARCHAR(140) |
| Dynamic Link | 对任意 DocType 的引用 | VARCHAR(140) |
| Select | 从选项中单选 | VARCHAR(140) |
| Table | 子表行 | 独立表 |
| Table MultiSelect | 多选链接行 | 独立表 |
| Check | 布尔值 0/1 | TINYINT |
| Int | 整数 | INT |
| Float | 小数(9 位) | DECIMAL |
| Currency | 金额(6 位小数) | DECIMAL |
| Date | 日历日期 | DATE |
| Datetime | 日期 + 时间 | DATETIME |
| Text Editor | 富文本(HTML) | LONGTEXT |
| Attach | 文件引用 | VARCHAR(140) |
| Small Text | 简短多行文本 | TEXT |
| Long Text | 无限长度文本 | LONGTEXT |
包含 35 种以上类型的完整字段类型参考:references/fieldtypes.md
基本字段属性
| 属性 | 类型 | 用途 |
|---|---|---|
reqd | bool | 字段为必填项 |
unique | bool | 数据库 UNIQUE 约束 |
search_index | bool | 为数据库创建 INDEX 以加快查询 |
in_list_view | bool | 在列表视图列中显示 |
in_standard_filter | bool | 在列表视图中显示为筛选条件 |
in_preview | bool | 在文档预览中显示 |
allow_on_submit | bool | 提交后可编辑 |
read_only | bool | 用户不可编辑 |
hidden | bool | 不在表单中显示 |
depends_on | str | 可见性条件(例如 eval:doc.status=="Active") |
mandatory_depends_on | str | 条件必填 |
read_only_depends_on | str | 条件只读 |
fetch_from | str | 从关联文档自动填充(例如 customer.customer_name) |
fetch_if_empty | bool | 仅在字段为空时获取 |
options | str | 特定于字段类型的选项(DocType 名称、选择项等) |
default | str | 默认值(支持 __user、Today 等) |
description | str | 显示在字段下方的帮助文本 |
collapsible | bool | 区块默认折叠(仅适用于 Section Break) |
决策树:选择哪种 DocType?
Need to store data?
├─ YES: Need multiple records?
│ ├─ YES: Need submit/cancel workflow?
│ │ ├─ YES → Standard DocType + is_submittable=1
│ │ └─ NO: Need hierarchy/tree?
│ │ ├─ YES → Tree DocType (is_tree=1)
│ │ └─ NO: Embedded in parent?
│ │ ├─ YES → Child DocType (istable=1)
│ │ └─ NO → Standard DocType
│ └─ NO: Single config/settings → Single DocType (issingle=1)
└─ NO: Data from external source → Virtual DocType (is_virtual=1)
命名规则
始终在 DocType 上设置 naming_rule。autoname 字段用于存放模式。
| naming_rule 值 | autoname 模式 | 示例输出 |
|---|---|---|
| Set by User | (empty) | 用户手动输入名称 |
| Autoincrement | (empty) | 1、2、3 |
| By Fieldname | field:{fieldname} | 该字段的值 |
| By Naming Series | naming_series: | INV-2024-00001(来自序列字段) |
| Expression | PRE-.##### | PRE-00001、PRE-00002 |
| Expression (Old Style) | {prefix}-{YYYY}-{#####} | INV-2024-00001 |
| Random | hash | 随机 10 字符字符串 |
| UUID | (empty) | 550e8400-e29b-... |
| By Script | (custom) | 由控制器的 autoname() 决定 |
绝不要在生产环境中使用 Autoincrement——删除记录后会出现间隙。请改用 Expression 或 Naming Series。
完整命名参考:references/naming.md
子表设计
Child DocType 是设置了 istable=1 的 DocType。它始终属于某个父项。
父项一侧——添加一个字段,设置:
fieldtype:Table(或Table MultiSelect)options:Child DocType 名称
子记录会自动获得:
parent——父文档的名称parenttype——父项的 DocTypeparentfield——父项中 Table 字段的 fieldnameidx——行顺序(从 1 开始)
# Adding child rows programmatically
doc = frappe.get_doc("Sales Invoice", "INV-001")
doc.append("items", {
"item_code": "ITEM-001",
"qty": 5,
"rate": 100.0
})
doc.save()
绝不要创建未设置
istable=1的 Child DocType。绝不要在 Table 字段中引用非子项 DocType。
Table 与 Table MultiSelect
| 方面 | Table | Table MultiSelect |
|---|---|---|
| UI | 完整可编辑网格,带有“添加行” | 标签式选择器,没有“添加行” |
| Child DocType | 包含多个字段的完整子项 | 通常仅包含 1 个 Link 字段 |
| 使用场景 | 行项目、明细行 | 多选引用 |
Single DocType(设置模式)
设置 issingle=1。数据以键值对形式存储在 tabSingles 中,而非专用表中。
# Access Single DocType
settings = frappe.get_single("My Settings")
value = settings.some_field
# Or directly
value = frappe.db.get_single_value("My Settings", "some_field")
- 绝不要期待 Single DocType 有列表视图——它们恰好只有一个实例。
- 始终将其用于应用级配置(API 密钥、默认值、功能开关)。
Tree DocType(NestedSet)
设置 is_tree=1。Frappe 会自动添加 lft、rgt、parent_{doctype_fieldname}、old_parent 列。
- 始终在 DocType JSON 中定义
parent_field(例如,为 Chart of Accounts 定义parent_account)。 - NestedSet 模型使用
lft/rgt整数来高效查询子树。 - 绝不要手动编辑
lft/rgt值。如果数据损坏,请使用frappe.utils.nestedset.rebuild_tree()。
# Get all descendants
descendants = frappe.get_all("Account",
filters={"lft": [">", node.lft], "rgt": ["<", node.rgt]})
# Get ancestors (path to root)
ancestors = frappe.get_all("Account",
filters={"lft": ["<", node.lft], "rgt": [">", node.rgt]},
order_by="lft asc")
Virtual DocType
设置 is_virtual=1。不会创建数据库表。始终实现以下控制器方法:
class MyVirtualDoc(Document):
def db_insert(self, *args, **kwargs):
# Persist to your custom backend
pass
def load_from_db(self):
# Load document data from your source
pass
def db_update(self, *args, **kwargs):
# Update in your custom backend
pass
def delete(self):
# Remove from your custom backend
pass
@staticmethod
def get_list(args):
# Return list of documents
pass
@staticmethod
def get_count(args):
# Return total count
pass
@staticmethod
def get_stats(args):
# Return statistics
pass
绝不要对 Virtual DocType 数据调用
frappe.db.*——这些调用只适用于站点数据库,不适用于自定义后端。
自定义 API
自定义字段(程序化)
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
# Dict format: {DocType: [field_dicts]}
create_custom_fields({
"Sales Invoice": [
dict(fieldname="custom_tracking", label="Tracking ID",
fieldtype="Data", insert_after="naming_series")
],
"Purchase Order": [
dict(fieldname="custom_vendor_ref", label="Vendor Ref",
fieldtype="Data", insert_after="supplier")
]
}, update=True)
Property Setter(程序化)
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
# Change a field property on an existing DocType
make_property_setter("Sales Invoice", "customer", "reqd", 1, "Check")
make_property_setter("Sales Invoice", "posting_date", "default", "Today", "Text")
完整自定义参考:references/customization.md
数据遮蔽(v16+)
设置了 mask=1 的字段,会向在该字段的 permlevel 上没有 mask 权限的用户隐藏敏感值。服务器会在向客户端发送值前,将其替换为 XXXXXXXX 等模式。管理员始终可以看到未遮蔽的值。
{ "fieldname": "phone", "fieldtype": "Data", "options": "Phone", "mask": 1, "permlevel": 1 }
完整遮蔽参考:references/data-masking.md
Python 类型存根
Frappe 会通过 TypeExporter 在控制器文件中自动生成类型注解。字段会在 TYPE_CHECKING 守卫内获得 DF.* 类型:
if TYPE_CHECKING:
from frappe.types import DF
customer: DF.Link
items: DF.Table[SalesInvoiceItem]
status: DF.Literal["Draft", "Submitted", "Paid"]
绝不要修改 # begin: auto-generated types 与 # end: auto-generated types 之间的代码。
完整类型存根参考:references/type-stubs.md
关键规则
- 始终以单数形式命名 DocType(“Sales Invoice”,而不是“Sales Invoices”)。
- 始终在脑中加上
tab前缀——数据库表是tabSales Invoice。 - Data/Link/Select 字段值的长度不得超过 140 个字符。
- 对频繁用于筛选或
get_list调用的字段,始终设置search_index=1。 - 对用户经常筛选的字段,始终设置
in_standard_filter=1。 - 子表字段若会影响计算,且不会重新计算总计,则绝不要设置
allow_on_submit=1。 - 除非希望覆盖用户的编辑,否则始终在
fetch_from旁设置fetch_if_empty=1。 - 绝不要使用原始 Python 定义
depends_on——请使用eval:doc.fieldname == "value"语法。
另请参阅
- references/fieldtypes.md -- 完整的字段类型参考
- references/naming.md -- 所有命名方法及示例
- references/examples.md -- 实际的 DocType JSON 示例
- references/anti-patterns.md -- 常见的架构设计错误
- references/customization.md -- Custom Fields 和 Property Setter API
- references/data-masking.md -- 字段级数据脱敏,保护隐私(v16+)
- references/type-stubs.md -- Python 类型提示、DF 类型、TypeExporter