关于 frappe-web-forms
此技能面向 Frappe 开发者,指导创建供外部用户填写和提交数据的 Web 表单。内容涵盖访问控制、定制及服务器端验证。
主要功能
- 01创建并发布 Web 表单
- 02配置登录与编辑权限
- 03添加服务器端和客户端定制
- 04管理文件上传与表单样式
适用场景
- 01创建支持工单提交表单
- 02收集客户反馈或注册信息
- 03提供无需 Desk 访问的自助数据录入
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ lubusin/ frappe-skills --skill frappe-web-forms安装后在 Claude Code 中输入/frappe-web-forms确认已加载。
附带文件references/web-forms.md
详细介绍
Frappe Web Forms
构建面向公众的 Web 表单,用于数据收集、提交和客户自助服务。
适用场景
- 为外部用户创建表单(无需访问 Desk)
- 构建支持请求/工单提交表单
- 收集客户反馈或注册信息
- 启用自助数据录入门户
- 用基于表单的工作流替代简单的门户页面
所需输入
- 表单提交所针对的 DocType
- 要在 Web 表单中公开的字段
- 身份验证要求(必须登录还是允许访客)
- 用户是否可以编辑/重新提交条目
- 文件上传要求
操作步骤
0)准备工作
确保目标 DocType 已存在,且包含要公开的字段。
1)创建 Web 表单
- 在 awesomebar 中输入“new web form”
- 输入标题(将成为 URL slug)
- 选择用于创建记录的 DocType
- 添加介绍文字(可选,显示在表单上方)
- 点击“Get Fields”导入所有字段,或手动添加字段
- 设置字段顺序,并指定必填字段
- 发布表单
2)配置设置
| 设置 | 用途 |
|---|---|
| Login Required | 要求先通过身份验证才能访问表单 |
| Allow Edit | 允许用户编辑已提交的条目 |
| Allow Multiple | 允许用户提交多个条目 |
| Show as Card | 以卡片布局样式显示 |
| Max Attachment Size | 限制文件上传大小 |
| Success URL | 成功提交后重定向到指定页面 |
| Success Message | 提交后显示自定义消息 |
3)将其设为标准 Web 表单(随应用打包)
勾选“Is Standard”(在 Developer Mode 中可见),将表单导出为文件:
my_app/
└── my_module/
└── web_form/
└── contact_us/
├── contact_us.json # Web form metadata
├── contact_us.py # Server-side customization
└── contact_us.js # Client-side customization
4)添加服务器端自定义
# contact_us.py
import frappe
def get_context(context):
"""Add custom context variables to the web form."""
context.categories = frappe.get_all("Support Category",
filters={"enabled": 1},
fields=["name", "label"],
order_by="label asc"
)
def validate(doc):
"""Custom validation before the document is saved."""
if not doc.email:
frappe.throw("Email address is required")
# Prevent duplicate submissions
existing = frappe.db.exists("Support Ticket", {"email": doc.email, "status": "Open"})
if existing:
frappe.throw("You already have an open ticket. Please wait for a response.")
5)添加客户端自定义
// contact_us.js
frappe.ready(function() {
// Handle field changes
frappe.web_form.on("field_change", function(field, value) {
if (field === "category" && value === "Urgent") {
frappe.web_form.set_df_property("description", "reqd", 1);
}
});
// Custom validation
frappe.web_form.validate = function() {
let data = frappe.web_form.get_values();
if (data.phone && !data.phone.match(/^\+?[0-9\-\s]+$/)) {
frappe.msgprint("Please enter a valid phone number");
return false;
}
return true;
};
// Custom after-save behavior
frappe.web_form.after_save = function() {
frappe.msgprint("Thank you for your submission!");
};
});
6)控制权限
- 访客访问:取消勾选“Login Required”,以开放完全公开的表单
- 门户角色:分配门户角色,以控制哪些已登录用户可以看到表单
- 用户权限:在目标 DocType 上设置明确的文档级权限
- 行级访问:使用 User Permission 规则限制用户可编辑的记录
7)设置 Web 表单样式
Web 表单默认使用网站主题。如需自定义样式:
<style>
.web-form-container { max-width: 600px; margin: 0 auto; }
.web-form-container .form-group { margin-bottom: 1.5rem; }
.web-form-container .btn-primary { background-color: #2490EF; }
</style>
验证
- Web 表单可通过正确的 URL 访问(
/contact-us) - 所有字段均正确呈现
- 必填字段验证正常
- 提交后创建了正确的 DocType 记录
- 登录要求已生效(如已配置)
- 编辑和重新提交功能正常(如已配置)
- 文件上传正常,且未超出大小限制
- 提交后成功消息/重定向正常
- 自定义 Python 验证在提交时运行
故障情况/调试
- 无法访问表单:检查表单是否已发布;确认 URL slug
- 提交时权限被拒绝:检查 Website User 或 Guest 对 DocType 的权限
- 字段未显示:确保已将字段添加到 Web 表单中(而不只是添加到 DocType)
- 自定义 JS 未加载:检查浏览器控制台;确保文件路径正确
- 未触发验证:确认 Python 文件中的
validate函数能正确返回/抛出结果 - 重复条目:检查“Allow Multiple”设置;添加自定义重复项检测
升级处理
- DocType 架构 →
frappe-doctype-development - Frappe UI 门户应用 →
frappe-frontend-development - API 端点访问 →
frappe-api-development
参考资料
- references/web-forms.md — Web 表单的创建和自定义
防护措施
- 在服务器端验证输入:绝不要信任客户端验证;在 Python 的
validate()方法中进行检查 - 公开表单使用验证码:为访客可访问的表单启用 reCAPTCHA,以防止垃圾信息
- 清理输出内容:显示用户提交的数据时进行转义;使用
frappe.utils.escape_html() - 限制文件上传:为附件字段设置最大文件大小和允许的类型
- 检查速率限制:考虑对来自同一 IP 的表单提交进行限流
常见错误
| 错误 | 失败原因 | 修复方法 |
|---|---|---|
| 缺少 DocType 权限 | 提交时出现“Permission denied” | 为 Website User 或 Guest 角色授予 Create 权限 |
| 未处理文件上传 | 文件未附加到记录 | 正确配置 Attach 字段;检查上传限制 |
| XSS 漏洞 | 安全风险 | 在显示时转义用户输入;在模板中使用 ` |
| 忘记发布表单 | 出现 404 错误 | 检查 Web Form 中的“Published”复选框 |
| 仅进行客户端验证 | 数据库中存在无效数据 | 在 Web Form Python 文件中添加 validate() 方法 |
| 未以访客用户身份测试 | 管理员可用,用户却无法使用 | 在隐身模式或退出登录状态下测试 |
评论
支持 Markdown