mcpField
F
frappe-core-files

frappe-core-files

github.com/impertio-studio开发198112 次安装30 周前更新
代码仓库

关于 frappe-core-files

面向 Frappe 开发者的文件管理参考技能,适用于处理附件和文件记录。内容包括程序化及 API 操作、存储路径、隐私权限和自定义存储钩子。

主要功能

  1. 01保存、读取、附加和删除文件
  2. 02通过 REST API 上传文件
  3. 03公共与私有文件的访问规则
  4. 04文件路径和附件字段
  5. 05自定义存储钩子与配置

适用场景

  1. 01将生成的文件附加到 Frappe 文档
  2. 02通过 REST API 上传文档
  3. 03为敏感附件设置访问规则

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/impertio-studio/frappe_claude_skill_package --skill frappe-core-files

安装后在 Claude Code 中输入/frappe-core-files确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
.gitkeep
anti-patterns.md
examples.md

详细介绍

Frappe 文件管理

快速参考

操作方法说明
从字节保存文件save_file(fname, content, dt, dn)返回 File 文档
从 URL 保存文件save_url(file_url, fname, dt, dn)根据 URL 创建 File 文档
读取文件内容frappe.get_file(fname)返回 [filename, content]
获取文件路径get_file_path(file_name)解析为绝对路径
通过 HTTP 上传POST /api/method/upload_fileMultipart 表单上传
删除文件frappe.delete_doc("File", name)删除文档和文件系统中的文件
附加打印文件frappe.attach_print(dt, dn, print_format)返回 {"fname", "fcontent"}
获取缓存文档frappe.get_cached_doc("File", name)只读,已缓存

决策树

What file operation do you need?
│
├─ Upload a file from user input?
│  ├─ Via web form → Attach field type (auto-handles upload)
│  └─ Via API → POST /api/method/upload_file
│
├─ Create a file programmatically?
│  ├─ From bytes/content → save_file(fname, content, dt, dn)
│  ├─ From external URL → save_url(file_url, fname, dt, dn)
│  └─ Full control → frappe.get_doc({"doctype": "File", ...}).insert()
│
├─ Read file content?
│  ├─ By filename → frappe.get_file(fname)
│  └─ By File doc → file_doc.get_content()
│
├─ Public or private?
│  ├─ Public (anyone with link) → is_private=0, URL: /files/fname
│  └─ Private (permission-based) → is_private=1, URL: /private/files/fname
│
└─ Generate PDF attachment?
   └─ frappe.attach_print(doctype, name, print_format)

File DocType:核心字段

字段类型描述
file_nameData不含路径的文件名
file_urlDataURL 路径(例如,/files/report.pdf)
file_typeData扩展名(PDF、PNG、DOCX 等)
is_privateCheck0 = 公开,1 = 私有
is_folderCheck文件夹条目为 True
folderLink → File父文件夹
attached_to_doctypeLink → DocType父文档类型
attached_to_nameData父文档名称
attached_to_fieldData父文档上的字段名称
content_hashData用于去重的 SHA-256
file_sizeInt大小,单位为字节

文件 URL 模式

类型URL 模式文件系统路径
公开/files/{filename}{site}/public/files/{filename}
私有/private/files/{filename}{site}/private/files/{filename}
远程https://...不在本地存储
API/api/method/{path}动态生成

有效的 URL 前缀:http://、https://、/api/method/、/files/、/private/files/。

对于敏感文档,始终使用 /private/files/。任何知道 URL 的人都可以访问公开文件,包括未通过身份验证的用户。


权限模型

Frappe 文件采用三层权限模型:

  1. 管理员 — 可不受限制地访问所有文件
  2. 公开文件(is_private=0)— 任何知道 URL 的人都可以读取(读取时无需身份验证)
  3. 私有文件(is_private=1)— 访问者必须满足以下条件之一:
    • 用户是文件所有者,或
    • 用户对该文件拥有明确的共享权限,或
    • 用户对 attached_to_doctype/attached_to_name 文档拥有读取权限

切勿将敏感数据存储为公开文件。对于包含个人数据、财务记录或机密信息的文档,务必设置 is_private=1。


以编程方式操作文件

从内容保存文件
from frappe.utils.file_manager import save_file

# Save a generated CSV
csv_content = "Name,Amount\nACME,1000\nGlobex,2000"
file_doc = save_file(
    fname="report.csv",
    content=csv_content.encode("utf-8"),
    dt="Sales Invoice",           # attach to this DocType
    dn="SINV-00001",              # attach to this document
    folder="Home/Attachments",    # optional folder
    is_private=1,                 # private file
)
# file_doc.file_url → "/private/files/report.csv"
从 URL 保存文件
from frappe.utils.file_manager import save_url

file_doc = save_url(
    file_url="https://example.com/logo.png",
    filename="company-logo.png",
    dt="Company",
    dn="My Company",
    folder="Home",
    is_private=0,
)
读取文件内容
# By filename
filename, content = frappe.get_file("report.csv")

# By File document
file_doc = frappe.get_doc("File", {"file_name": "report.csv"})
content_bytes = file_doc.get_content()
直接创建文件文档
file_doc = frappe.get_doc({
    "doctype": "File",
    "file_name": "generated-report.pdf",
    "attached_to_doctype": "Sales Invoice",
    "attached_to_name": "SINV-00001",
    "is_private": 1,
    "content": pdf_bytes,  # raw bytes — written to disk on insert
}).insert(ignore_permissions=True)
生成并附加 PDF
# Create PDF attachment dict (for use with sendmail)
pdf_attachment = frappe.attach_print(
    "Sales Invoice",
    "SINV-00001",
    print_format="Standard",
)
# Returns: {"fname": "Sales Invoice - SINV-00001.pdf", "fcontent": <bytes>}

# Save PDF as file attachment
from frappe.utils.file_manager import save_file

pdf = frappe.get_print("Sales Invoice", "SINV-00001", print_format="Standard", as_pdf=True)
save_file("invoice.pdf", pdf, "Sales Invoice", "SINV-00001", is_private=1)

通过 REST API 上传文件

# Upload file attached to a document
curl -X POST https://site.example.com/api/method/upload_file \
  -H "Authorization: token api_key:api_secret" \
  -F "file=@/path/to/document.pdf" \
  -F "doctype=Sales Invoice" \
  -F "docname=SINV-00001" \
  -F "is_private=1"

响应:

{
  "message": {
    "name": "FILE-00001",
    "file_name": "document.pdf",
    "file_url": "/private/files/document.pdf",
    "is_private": 1
  }
}

文件大小和扩展名限制

**默认最大文件大小:**每个附件 10 MB。

在 site_config.json 中覆盖:

{
  "max_file_size": 20971520
}

**每个文档的最大附件数:**通过「自定义表单」→ DocType 上的「最大附件数」字段设置。

以编程方式检查文件大小:

from frappe.utils.file_manager import check_max_file_size
check_max_file_size(content)  # raises MaxFileSizeReachedError if too large

附件字段类型

字段类型存储内容界面
Attach单个文件 URL文件选择器 + 上传按钮
Attach Image单个图片 URL图片预览 + 上传

两者都会在字段值中存储 file_url 字符串。File DocType 记录会单独创建,并设置 attached_to_field。


S3 / 云存储集成

Frappe 支持通过 delete_file_data_content hook 和自定义上传处理程序使用自定义文件存储。

通过 frappe-s3-attachment 或类似应用使用 S3
# In hooks.py of custom app
delete_file_data_content = "my_app.storage.delete_from_s3"

使用自定义存储后端时,务必测试文件删除功能——默认的 delete_file_from_filesystem 只处理本地文件。

配置模式
# site_config.json for S3-compatible storage
{
  "s3_bucket": "my-frappe-files",
  "s3_region": "eu-west-1",
  "s3_access_key": "AKIA...",
  "s3_secret_key": "...",
}

版本差异

特性v14v15v16
文件 DocType可用可用可用
content_hash 去重可用可用可用
图像优化手动自动(1920x1080,85%)自动
Zip 导入/导出不可用可用可用

另请参阅

评论

支持 Markdown