单据状态

Frappe 使用“文档状态”(Docstatus)的概念来跟踪交易的状态。文档状态始终为以下三个值之一:

  1. 草稿(值:0)
  2. 已提交(值:1)
  3. 已取消(值:2)

不可提交的文档将始终保持在“草稿”状态。可提交的文档可以选择从草稿状态进入“已提交”状态,然后进入“已取消”状态。

处于已提交和已取消状态的文档无法编辑,但有一个例外:对于个别字段,我们可以明确允许编辑,即使文档处于已提交状态。

在后端代码中,我们有一个辅助类 DocStatus,可以按如下方式使用:

import frappe
from frappe.model.docstatus import DocStatus

draft_invoice_names = frappe.get_list(
 "Sales Invoice",
 filters={"docstatus": DocStatus.draft()},
 pluck="name"
)

invoice_doc = frappe.get_doc("Sales Invoice", draft_invoice_names[0])
invoice_doc.docstatus == DocStatus.draft() # -> True
invoice_doc.docstatus.is_draft() # -> True
invoice_doc.docstatus.is_submitted() # -> False
invoice_doc.docstatus.is_cancelled() # -> False

invoice_doc.submit()
invoice_doc.docstatus == DocStatus.submitted() # -> True
invoice_doc.docstatus.is_draft() # -> False
invoice_doc.docstatus.is_submitted() # -> True
invoice_doc.docstatus.is_cancelled() # -> False

invoice_doc.cancel()
invoice_doc.docstatus == DocStatus.cancelled() # -> True
invoice_doc.docstatus.is_draft() # -> False
invoice_doc.docstatus.is_submitted() # -> False
invoice_doc.docstatus.is_cancelled() # -> True

文档状态以整数值的形式存储在数据库的每个 DocType 表中。

审计追踪

说明

一个用于查看可提交文档类型在多个修订版本中所做更改的工具。当可提交文档被取消并修订时,由于文档名称发生变化,使用版本文档类型来跟踪文档更改会变得困难。审计追踪可用于查看可提交文档类型的最多 5 个先前修订版本

步骤

  1. 文档类型字段中选择文档的类型。
  2. 文档字段中选择文档的名称。
  3. 可选:选择开始和结束日期,以显示指定日期范围内的修订文档。
  4. 点击“比较”按钮,查看所选文档的审计追踪。

更改的字段

不同版本中发生更改的字段值。

更新的行

不同版本中子表字段发生更改的值。

添加的行 / 删除的行

不同版本中每个子表添加或删除的行。

配置

Frappe 站点可以共享同一个应用服务器,每个站点可以使用不同的数据库解决方案、配置和位置,并可通过 Bench 中的站点配置实现不同粒度的管理。

站点配置存储了所有与站点相关的信息,从站点的数据库详情到指向该站点的自定义域名。通过站点配置,我们可以定义可能改变 Frappe 和您的 Frappe 应用行为的键值对。

站点配置

site_config.json 存储特定站点的全局配置,位于站点目录中。该文件由 Frappe 自动创建并填充。由于这依赖于 Frappe,默认设置或行为也可能因任何更新而改变。

{
  "db_name": "frappe_database_name",
  "db_password": "frappe_database_password",
  "admin_password": "admin_password",
}

注意:此文件被视为包含与站点状态相关的重要信息,如果配置文件丢失或损坏,可能会带来麻烦。在标准设置中,它会与数据库备份一起定期备份。

通用站点配置

common_site_config.json 存储您的 bench 共享的配置。在 Bench 级别执行的操作通常与此配置相关。定义的配置键可用于改变 bench 级别操作的行为,或影响您 bench 上的所有站点,具体取决于配置值的优先级。

此文件由 Bench CLI 自动生成和管理。此文件的更改可能会影响您的 Frappe 设置的行为,具体取决于您的系统设置和 Bench CLI 的版本。

{
  "background_workers": 1,
  "developer_mode": true,
  "dns_multitenant": true,
  "file_watcher_port": 6789,
  "frappe_user": "frappe",
  "gunicorn_workers": 2,
  "maintenance_mode": 0,
  "pause_scheduler": 0,
  "redis_cache": "redis://localhost:13000",
  "redis_cache_sentinel_enabled": 1,
  "redis_cache_sentinels": [
    "redis-cache-sentinel-1:26379",
    "redis-cache-sentinel-2:26379"
  ],
  "redis_cache_sentinel_password": "sentinelpassword",
  "redis_cache_master_service": "mymaster",
  "redis_cache_master_password": "masterpassword",
  "redis_queue": "redis://localhost:11000",
  "redis_queue_sentinel_enabled": 1,
  "redis_queue_sentinels": [
    "redis-queue-sentinel-1:26379",
    "redis-queue-sentinel-2:26379"
  ],
  "redis_queue_sentinel_password": "sentinelpassword",
  "redis_queue_master_service": "mymaster",
  "redis_queue_master_password": "masterpassword",
  "redis_socketio": "redis://localhost:12000",
  "scheduler_tick_interval": 120,
  "serve_default_site": true,
  "socketio_port": 9000,
  "webserver_port": 8000,
  "root_password": "MARIADB_PASSWORD",
  "live_reload": true
}

可选设置

workers 允许创建自定义 worker。background_workers 参数是可选的,如果未设置,将使用通用的 background_workers。示例:"workers": { "custom_worker1": { "timeout": 5000, "background_workers": 4 } }。重新生成配置并重启进程以生效。
redis_cache_sentinel_enabled 如果设置为 1,则在生产环境中连接到 Redis sentinel
redis_cache_sentinels sentinel 服务器主机/ IP 和端口的数组
redis_cache_sentinel_password 连接到 sentinel 的密码
redis_cache_master_service 要连接的主服务
redis_cache_master_password Redis 主服务器密码
redis_queue_sentinel_enabled 如果设置为 1,则在生产环境中连接到 Redis sentinel
redis_queue_sentinels sentinel 服务器主机/ IP 和端口的数组
redis_queue_sentinel_password 连接到 sentinel 的密码
redis_queue_master_service 要连接的主服务
redis_queue_master_password Redis 主服务器密码

除此之外,您可以设置任何希望对所有站点可用的键。

配置值优先级

site_config.json 中设置的特定键的值将优先于在 common_site_config.json 中定义的值。这意味着通用配置中定义的键值在某些情况下可以用作回退。

假设您想在 bench 上的所有站点上启用 Frappe Web Logger,但 worker.frappe.xyz 除外,因为假设它是一个高活动站点,您不需要同时被大量信息淹没。您可以在 common_site_config.json 中将 enable_frappe_logger 设置为 true,并在 worker.frappe.xyzsite_config.json 中将其设置为 false

$ bench config set-common-config -c enable_frappe_logger true
$ bench --site worker.frappe.xyz set-config enable_frappe_logger false

类似地,可以有一个应用服务器来支持多个站点,每个站点使用不同的数据库解决方案提供商或位置。如果您选择将 bench 上的所有站点迁移到另一个数据库服务器,切换可能只需更新 bench 的 common_site_config.json 中的值即可。

标准配置键

这些是 Frappe Framework 和 Bench 使用的一些标准键。

强制设置

这些键在 site_config.json 中设置,除非在站点创建期间提供了值,否则会自动生成。

db_type 数据库类型。选项包括 “mariadb” 和 “postgres”。
db_name 数据库名称(也用作默认数据库用户名)。
db_password 数据库密码。

可选设置

admin_password 标准 “Administrator” 用户的默认密码。这将用作所有新站点的 Administrator 用户的密码。
allow_tests 设置此项允许在此站点上运行测试。
allow_cors 启用跨站点 HTTP 请求。可以设置为: – 特定来源,例如:"https://example.com" – 来源列表,例如:["https://portal.example.com", "https://shop.example.com"] – 通配符:"*"(不建议用于生产环境)
allowed_referrers 此处提到的域将允许绕过 CSRF,如果它们是请求的来源或引用者
backup_encryption_key 用于加密/解密备份的密钥
data_import_batch_size 数据导入的批量大小
db_user 从 v16 开始,请指定单独的数据库用户名
deny_multiple_logins 阻止用户拥有多个活动会话。
deny_multiple_sessions 拒绝多个会话。
developer_mode 如果设置了开发者模式,DocType 的更改会自动更新到文件中。
disable_async 禁用 socket.io 客户端;客户端将停止轮询 socket.io 服务器。
disable_error_snapshot 禁用错误快照。
disable_global_search 禁用全局搜索。
disable_scheduler 禁用调度器
disable_session_cache 禁用会话缓存。
disable_website_cache 禁用网站缓存。
encryption_key 用于加密密码的密钥。此密码会在新站点上自动创建。在站点恢复时,也需要恢复此密钥才能使用现有密码。
enable_frappe_logger 如果设置,将记录请求的基本信息并保存到 ./sites/{site}/logs/frappe.web.log 下。
error_report_email 设置默认的错误报告电子邮件。
ignore_csrf 忽略 CSRF。
install_apps 在站点 restorereinstallnew 创建时,列出要安装的应用。
host_name 后台任务和打印需要此主机名来正确识别站点 URL。该值应包含协议和端口(如果不是默认端口),末尾不要带斜杠。例如:"https://erp.example.org:2424"
http_port 更改 Frappe 设置的 HTTP 端口。
keep_backups_for_hours frappe.utils.new_backup 中用于传递 frappe.utils.delete_temp_backups。它根据备份文件的年龄(以小时计)来保留备份文件。
local_infile 设置标志以允许 MySQL 连接使用本地 infile 数据。
logging 通过 frappe.log 使用 frappe.debug_log 来启用不同级别的日志记录。在级别 2,显示每次操作运行的查询和结果。
maintenance_mode 启用维护模式。
max_file_size 允许上传的最大文件大小。默认值为 10MiB。
max_reports_per_user 用户可创建的最大自动邮件报告数量,默认为 3。
monitor 如果设置,将记录所有请求并保存到 ./logs/monitor.json.log 下。请参阅调试文档中的监控部分。
mute_emails 如果为 true,则停止发送电子邮件。
pause_scheduler 暂停调度器
rate_limit 使用 frappe.rate_limiter 指定速率限制。请参阅文档中的速率限制参考。
robots_txt 访问 frappe-site.com/robots.txt 时要呈现的 robots.txt 文件路径
root_login 数据库根用户名。
root_password 数据库根密码。
server_script_enabled 启用/禁用服务器脚本。
skip_setup_wizard 跳过设置向导。
socketio_backend 指定 Socket.IO 后端服务器实现。node (default) or python
socketio_port 指定 Socket.IO 端口。
webserver_port 通常用作配置键 http_port 的回退。
app_include_js 通过 URL 在 /app 中注入 JavaScript 脚本。必须是绝对 URL 的列表。
app_include_css 通过 URL 在 /app 中注入 CSS 样式表。必须是绝对 URL 的列表。
disable_transaction_log 禁用为销售发票付款条目创建交易日志ERPNext 区域功能)。

远程数据库主机设置

要使用 SSL 连接到远程数据库服务器,必须先配置数据库主机以接受 SSL 连接。有关如何执行此操作的示例,请参阅 Digital Ocean 的教程。完成配置后,设置以下三个选项。必须设置所有选项,Frappe 才会尝试使用 SSL 连接。

db_host 数据库主机(如果不是 localhost)。
db_port 指定数据库的端口。
db_ssl_ca 用于通过 SSL 连接到数据库主机的 ca.pem 文件的完整路径。示例值为 "/etc/mysql/ssl/ca.pem"
db_ssl_cert 用于通过 SSL 连接到数据库主机的 cert.pem 文件的完整路径。示例值为 "/etc/mysql/ssl/client-cert.pem"
db_ssl_key 用于通过 SSL 连接到数据库主机的 key.pem 文件的完整路径。示例值为 "/etc/mysql/ssl/client-key.pem"
rds_db 在设置站点数据库时,授予某些特定权限而不是全部权限。在 db_manager.py 中使用。

副本只读数据库主机设置

在副本设置中,从辅助 MariaDB 服务器设置读取操作的指南可在用户指南中找到。

read_from_replica 用于启用或禁用从副本读取。可接受的值为 1/0 或 true/false。
different_credentials_for_replica 如果副本上的数据库凭据不同,则设置为 1,否则设置为 0
replica_host 副本的 IP 地址
replica_db_name 副本数据库名称
replica_db_password 副本数据库密码

默认外发邮件设置

以下是 Frappe 邮件模块中一些可用的较低级别配置。

auto_email_id 如果设置,这将是外发邮件的默认发件邮箱。
mail_login 作为第二优先选项使用,”[email protected]” 作为备用选项。
always_use_account_email_id_as_sender 使用账户邮箱 ID 作为发件人。
always_use_account_name_as_sender_name 使用账户名称作为发件人名称
email_sender_name 邮件发件人名称。
mail_server SMTP 服务器主机名。
mail_port SMTP 端口。
mail_login SMTP 服务器登录 ID。
mail_password SMTP 服务器密码。
pop_timeout POP 超时时间。
use_ssl 通过 SSL 连接。
use_tls 通过 TLS 连接。

Bench 配置

这些配置由 Bench 命令行工具使用,并且可以通过公共站点配置为系统上的每个 bench 进行不同设置。

restart_supervisor_on_update 在 bench 更新时重启 supervisord
restart_systemd_on_update 在 bench 更新时重启 systemd
release_bench 如果设置,当前 bench 将仅被视为执行发布的工具。
background_workers 分配给处理后台作业的工作进程数量。
dns_multitenant 如果设置,则为 Bench 开启 DNS 多租户功能。在生成 NGINX 配置时使用。
file_watcher_port 文件监视器的端口号
frappe_user 创建当前 Bench 的用户。
gunicorn_workers Gunicorn 工作进程数量。默认最小值为 2。
gunicorn_max_requests Gunicorn 工作进程重启前处理的请求数。默认值为 5000。
maintenance_mode 如果设置,将使站点离线并停止所有后台进程和计划任务。在站点迁移和 bench 更新操作期间使用。
pause_scheduler 如果设置,将暂停指定站点的调度器。
redis_cache Bench Procfile 中定义的 redis 缓存进程的端口号。
redis_queue Bench Procfile 中定义的 redis 队列进程的端口号。
redis_socketio Bench Procfile 中定义的 redis Socket.IO 进程的端口号。
scheduler_tick_interval 作业调度器运行一个循环,每 scheduler_tick_interval 秒将所有待执行的计划任务加入队列。这使得可以设置调度作业的最小频率。默认为 60。
socketio_port Bench Procfile 中定义的 Socket.IO 进程的端口号。
webserver_port Frappe Web 服务器的端口号。
live_reload 当资源重建时自动重新加载 Desk。

集成

如果您是服务提供商,某些第三方集成可能需要您为 bench 上的所有站点定义较低级别的配置。Frappe 允许您通过站点配置为您的集成定义这些配置设置。

沙盒

sandbox_api_key 沙盒 API 密钥
sandbox_api_secret 沙盒 API 密钥密码
sandbox_api_password 沙盒 API 密码
sandbox_api_username 沙盒 API 用户名
sandbox_publishable_key 沙盒可发布密钥
sandbox_signature 沙盒签名

DropBox

dropbox_access_key Dropbox 访问密钥
dropbox_broker_site Dropbox 代理站点
dropbox_secret_key Dropbox 密钥密码

PayPal

paypal_username PayPal 用户名
paypal_password PayPal 密码
paypal_signature PayPal 签名

其他

google_analytics_id Google Analytics ID
converted_rupee_to_paisa 为 RazorPay 设置将卢比转换为派萨

外部扩展配置

有时,用户可能不希望将数据库密码等配置值直接硬编码在站点配置 JSON 中。在这种情况下,站点正常设置后,您可以安装一个自定义应用,该应用允许通过返回一个字典来扩展站点配置,字典中包含您希望追加或覆盖的任何值。该应用可以按任何所需方式获取这些值,但最好使用低延迟的方式,因为它需要在每次请求站点时运行。

可以按如下方式进行配置(在初始站点设置和安装应用后执行)

{
    "extra_config": "vault.vault.conf_hook"
}

或者如果您有多个

{
    "extra_config": ["vault.vault.conf_hook1", "vault.vault.conf_hook2"]
}

自定义应用中该方法的一个示例是

def conf_hook() -> dict:
    password = get_password()
    return {"db_password": password}

从环境变量覆盖

某些配置值可以通过环境变量进行覆盖。

优先级为:环境变量 -> 站点配置 -> 默认值(如果 Frappe 已配置了默认值)

配置 环境变量
redis_queue FRAPPE_REDIS_QUEUE
redis_cache FRAPPE_REDIS_CACHE
db_type FRAPPE_DB_TYPE
db_socket FRAPPE_DB_SOCKET
db_host FRAPPE_DB_HOST
db_port FRAPPE_DB_PORT
db_user FRAPPE_DB_USER
db_name FRAPPE_DB_NAME
db_password FRAPPE_DB_PASSWORD

静态资产

本指南帮助您了解 Frappe Framework 中静态资源的提供方式。

assets 文件夹

静态文件从 frappe-bench/sites/assets 文件夹中提供。当您
为生产环境部署 Frappe 时,nginx 会直接提供该文件夹的内容。所有
静态文件的 URL 始终以 /assets 开头。位于
frappe-bench/sites/assets/hero.png 的文件可以通过 URL
/assets/hero.png 公开访问。

public 文件夹

每个应用都有自己的 public 文件夹,用于提供静态资源。
该文件夹会通过符号链接到 frappe-bench/sites/assets/[appname]。以下是
在 assets 文件夹上执行 tree 命令的输出结果。

~/frappe-bench
$ tree sites/assets -L 1
sites/assets
├── erpnext -> ~/frappe-bench/apps/erpnext/erpnext/public
└── frappe -> ~/frappe-bench/apps/frappe/frappe/public

这意味着,如果 [appname]/public/images/favicon.png 处存在文件,那么它
也会以符号链接的形式存在于 assets/[appname]/images/favicon.png,并且
可以通过 URL /assets/[appname]/images/favicon.png 公开访问。

打包资源

打包资源生成于
assets/[appname]/dist/jsassets/[appname]/dist/css。因此,它们
可以通过 URL /assets/[appname]/dist/js/main.bundle.[hash].js 访问。

站点资源

除了应用提供的静态文件外,每个站点还可以拥有自己的静态
文件,这些文件可能来自用户上传或站点备份。

用户上传

用户上传的公开文件存储在
frappe-bench/sites/[sitename]/public/files。存储在
frappe-bench/sites/[sitename]/public/files/profile.png 的文件可以通过
URL /files/profile.png 公开访问。

用户上传的私有文件存储在
frappe-bench/sites/[sitename]/private/files。存储在
frappe-bench/sites/[sitename]/private/files/profile.png 的文件可以通过
URL /private/files/profile.png 访问。私有文件仅在
用户获得授权后才能查看。

备份

为站点生成的任何本地备份都存储为
frappe-bench/sites/[sitename]/private/backups/20210502_182223-[sitename]-database.sql.gz
它可以通过 URL
/backups/20210502_182223-[sitename]-database.sql.gz 访问,并且仅当用户
获得授权后才能下载。

以下是 ls 命令的输出结果:

~/frappe-bench
$ ls -l sites/site1.test/private/backups
total 6160
-rw-r--r-- 1 farisansari staff 2429268 May 2 18:22 20210502_182223-site1_test-database.sql.gz
-rw-r--r-- 1 farisansari staff 278 May 2 18:22 20210502_182223-site1_test-site_config_backup.json

资产捆绑

本指南旨在帮助您理解 Frappe Framework 中静态资源打包的工作原理。

Frappe 自带一个富管理界面,可通过 /app 访问,这是一个使用现代 JavaScript 语法编写的单页应用(SPA),其样式使用 SASS(.scss)文件编写。这些文件无法被浏览器直接理解,因此在发送到浏览器解析和执行之前,需要先进行编译。

Frappe 自带一个资源打包器,可以编译客户端资源,例如:

  • .js (使用 importexport 的现代语法)
  • .ts (TypeScript 文件)
  • .vue (Vue 单文件组件)
  • .css (使用 PostCSS 处理的 CSS)
  • .scss (SASS 文件)
  • .sass (使用缩进语法的 SASS 文件)
  • .styl (Stylus 文件)
  • .less (Less 文件)

这些文件根据类型被编译为 .js.css 格式,然后发送到浏览器。

构建资源

要使用资源打包器编译资源,您需要在 frappe-bench 文件夹下运行以下命令:

$ bench build

您也可以通过指定 --apps 选项来为特定应用运行该命令。

# build only frappe assets
$ bench build --apps frappe

# build only frappe and erpnext assets
$ bench build --apps frappe,erpnext

监听模式

当您使用打包文件时,每次修改源文件后都需要重新运行构建命令。资源打包器提供了监听模式,它会监听文件系统的变化,并在文件发生更改时自动重新构建。

运行以下命令将启动一个长时间运行的进程,它会监听您的文件并在文件变化时重新构建。每次重新构建时,它都会记录一行包含“Compiled changes…”文本的日志。

$ bench watch
Watching for changes...
1:17:28 PM: Compiled changes...

您也可以通过指定 --apps 选项来为特定应用运行该命令。

# watch only erpnext assets
$ bench watch --apps erpnext

从版本 14 开始,如果在监听模式下资源被重新构建,Desk 将自动重新加载。此行为可以通过设置 LIVE_RELOAD 环境变量,或更改 common_site_config.json 中的 live_reload 值来切换。

打包文件

打包文件是资源打包器进行编译的资源入口点。例如,如果您的应用 public 文件夹中有一个名为 main.bundle.js 的文件,它将被打包器自动拾取并编译到 /assets/[app]/dist/js/main.bundle.[hash].js。根据输出内容计算出的唯一哈希值也会附加到文件名中,这对于浏览器中的缓存失效非常有用。

类似地,如果 public 文件夹中有一个名为 style.bundle.scss 的文件,它将被编译到 /assets/[app]/dist/css/style.bundle.css。请注意,扩展名从 .scss 变为了 .css,因为浏览器可以理解 CSS 文件,但不能理解 SASS 文件。打包文件可以存在于 public 文件夹中的任何嵌套级别,但它们始终会根据类型编译到 dist/jsdist/css 目录中。这意味着如果存在一个位于 public/main.bundle.js 的文件和另一个位于 public/src/main.bundle.js 的文件,后者的编译输出将覆盖前者。打包器也会对此类冲突打印警告。

更多打包输入和输出的示例:

输入 输出
[app]/public/main.bundle.js /assets/dist/[app]/js/main.bundle.[hash].js
[app]/public/src/main.bundle.js /assets/dist/[app]/js/main.bundle.[hash].js
[app]/public/src/utils/utils.bundle.js /assets/dist/[app]/js/utils.bundle.[hash].js
[app]/public/main.bundle.ts /assets/dist/[app]/js/main.bundle.[hash].js
[app]/public/main.bundle.css /assets/dist/[app]/css/main.bundle.[hash].css
[app]/public/styles/main.bundle.css /assets/dist/[app]/css/main.bundle.[hash].css
[app]/public/main.bundle.scss /assets/dist/[app]/css/main.bundle.[hash].css
[app]/public/main.bundle.sass /assets/dist/[app]/css/main.bundle.[hash].css
[app]/public/main.bundle.styl /assets/dist/[app]/css/main.bundle.[hash].css
[app]/public/main.bundle.less /assets/dist/[app]/css/main.bundle.[hash].css

从 npm 导入库

如果您熟悉现代 Web 开发,您可能需要从 npm 安装第三方库并在项目中使用。

假设您想在应用中使用 dayjs 库来处理日期和时间。首先,您需要在应用文件夹的根目录下运行以下命令,通过 yarn 安装它。

$ cd frappe-bench/apps/myapp
$ yarn add dayjs

现在,您可以像这样在源文件中导入它:

myapp/public/main.bundle.js

import * as dayjs from 'dayjs';

console.log(dayjs())

在 HTML 中包含打包资源

当打包文件被编译时,输出文件包含一个唯一的哈希值。因此,您不能硬编码文件的路径,因为下次您修改该文件时,哈希值会发生变化。Frappe 提供了一些辅助方法来解决这个问题。

在自定义 HTML 文件中包含资源

Jinja 方法 include_scriptinclude_style 将分别输出包含 .js.css 文件 HTML 标记的正确文件路径。

index.html



My App

 {{ include_style('style.bundle.css') }}

 {{ include_script('main.bundle.js') }}

index.html(渲染后)



My App

 <script type="text/javascript" src="/assets/myapp/dist/js/main.bundle.BYJXV4LB.js"></script>

在 app.html 中包含资源

如果您想从您的应用中包含打包资源到 /app 中,您可以使用
app_include_jsapp_include_css 将它们加载到 app.html 中。

[app]/hooks.py

app_include_js = ['main.bundle.js']
app_include_css = ['style.bundle.css']

获取打包资源路径

如果由于某些原因您只需要打包资源的路径,您可以使用
bundled_asset Jinja 方法来生成它。

Jinja

{{ bundled_asset('main.bundle.js') }}

渲染结果

/assets/myapp/dist/js/main.bundle.BYJXV4LB.js

Python API

这些 API 在 Python 中也可用。您可以从 jinja_globals.py 中导入它们。

from frappe.utils.jinja_globals import bundled_asset, include_script, include_style

bundled_asset('main.bundle.js')

/app 中延迟包含打包资源

如果您想在管理界面(/app)中延迟加载打包资源,您可以使用
frappe.require 方法。

frappe.require('main.bundle.js').then(() => {
 // main.bundle.js is now loaded
})

当您想根据某些条件加载代码时,这种方法非常有用。
首次页面加载不会受到影响,并且对性能更有利。

生产模式

当您将应用部署到生产环境时,您可以在生产模式下构建您的资源。在这种模式下,打包器会压缩您的打包最终输出,
从而减小文件大小。

要在生产模式下构建您的资源,请运行以下命令:

$ bench build --production

用户与权限

Frappe 自带用户认证系统。它处理用户账户、基于角色的权限以及基于 Cookie 的用户会话。

Frappe 中的用户认证系统开箱即用地提供了许多功能:

  1. 用户
  2. 角色
  3. DocType 权限
  4. 权限级别
  5. 角色权限管理器
  6. 用户权限
  7. 限制视图和表单
  8. 密码哈希
  9. 密码强度检查
  10. 登录尝试限流
  11. 第三方认证,如 OAuth、Google、Facebook 等

用户和角色

用户记录代表一个经过认证的用户,可以在系统中执行授权操作。一个用户可以分配多个角色。角色描述了一个用户可以对某个 DocType 执行哪些操作。

用户角色

例如,博客作者角色对 博客文章 DocType 具有读取、写入和创建权限,但对 博客分类 只有读取权限。

博客作者角色

DocType 权限

当您安装应用时,DocType 可以有一组默认的角色。要为 DocType 配置角色,您必须在 DocType 的权限表中添加它们。

DocType 权限

如果您展开该行,您会看到更多可以配置的选项。 DocType 权限

以下是这些选项及其说明的列表:

选项 说明
级别 分配给此角色的权限级别
如果用户是所有者 仅当用户是创建该文档的人时,限制才会生效
读取 允许读取文档
写入 允许编辑文档
创建 允许创建文档
删除 允许用户删除文档
提交 允许用户提交文档
取消 允许用户取消文档
修订 允许用户修订文档
报表 允许用户查看报表视图
导出 允许用户以 Excel/CSV 格式导出记录
导入 允许用户使用数据导入工具导入记录
设置用户权限 允许用户为其他用户应用用户权限
共享 允许用户与其他用户共享文档
打印 允许用户打印文档或生成 PDF
电子邮件 允许用户为该文档发送电子邮件

权限级别

权限级别可用于对文档中的字段进行分组,并为每个级别应用单独的角色。默认情况下,所有字段的权限级别都设置为 0。

权限级别

角色权限管理器

角色权限管理器是一个用于管理角色权限的用户工具。默认的权限集显示在这里,并且可以被覆盖。

用户权限

用户权限是可以按用户应用的另一组规则。它可用于限制包含特定链接字段值的文档。

例如,要限制用户 John 只能查看由他创建的博客文章,即博客作者 John。应创建具有以下值的用户权限记录。

用户权限记录

创建用户权限配置后,当用户登录查看博客文章列表时,他将只能看到由他创建的博客文章的受限视图。

受限的博客文章列表

自动角色

某些角色会自动对用户隐藏,这简化了编写需要全面权限的 DocType。以下是自动角色:

  1. “访客” – 此角色分配给所有人,包括未认证的用户。
  2. “所有” – 此角色分配给所有注册用户。这包括网站用户。
  3. “管理员” – 此角色分配给默认创建的 Administrator 用户。
  4. “后台用户” – [v15 新增] 此角色分配给所有用户类型为“系统用户”的用户,即他们是系统用户而非网站用户。

限制视图和表单

Frappe 框架允许您配置哪些模块、DocType 和视图对用户可见。要配置向用户显示哪些模块,请转到用户表单的允许模块部分。

要隐藏用户的 DocType,请使用角色权限管理器从角色中移除读取权限。

要控制页面和报表的权限,请使用页面和报表的角色权限工具。

密码哈希

Frappe 内置了密码哈希处理功能。密码会被加密并保存在一个名为 __Auth 的独立数据库表中。

MariaDB [_baa0f26509a564b6]> select * from __Auth;
+---------+------------------+-----------+-----------------------------------------------
| doctype | name             | fieldname | password
+---------+------------------+-----------+-----------------------------------------------
| User    | Administrator    | password  | $pbkdf2-sha256$29000$Xss5pxSC8F5rDSHEOEdo7Q$in
| User    | [email protected] | password  | $pbkdf2-sha256$29000$y7mXMoZQau09RwiBsLaWsg$h.
+---------+------------------+-----------+-----------------------------------------------

密码策略

Frappe 还支持密码强度检查。可以在系统设置的“安全”部分启用该功能。“最低密码评分”字段用于验证密码应达到的强度等级。

密码策略

登录尝试

Frappe 允许您配置在锁定账户之前允许的连续登录尝试次数,以及锁定的时间长度。

第三方认证

Frappe 支持第三方登录提供商。要设置登录提供商,您需要配置一个社交登录密钥。点击此处了解更多信息。

理解文档类型

  1. 简介

  2. 模块

  3. DocField

  4. 命名

  5. 控制器

    • 控制器方法
    • 控制器钩子
  6. 子 DocType

  7. 单例 DocType

  8. 虚拟 DocType

  9. 操作与链接

  10. 自定义 DocType

简介

DocType 是基于 Frappe 框架的任何应用程序的核心构建块。它描述了数据的模型视图。它包含数据存储了哪些字段,以及这些字段如何相互关联。它还包含数据的命名方式信息。此外,它还启用了丰富的对象关系映射(ORM)模式,我们将在本指南的后续部分讨论。当您创建 DocType 时,会生成一个 JSON 对象,该对象进而创建一个数据库表。

ORM 只是一种无需编写显式 SQL 语句即可在数据库中读取、写入和更新数据的简便方法。

约定

为了支持快速应用程序开发,Frappe 框架遵循一些标准约定。

  1. DocType 始终使用单数形式。如果您想在数据库中存储文章列表,应将 doctype 命名为 Article
  2. 表名以 tab 为前缀。因此,Article doctype 的表名为 tabArticle

创建 DocType 的标准方法是在 Desk 的搜索栏中输入 new doctype

ToDo DocType

DocType 不仅存储字段,还存储有关数据在系统中如何行为的其他信息。我们称之为元数据。由于这些元数据也存储在数据库表中,因此无需编写大量代码即可轻松地动态更改元数据。了解更多关于元数据的信息。

DocType 本身也是一个 DocType。这意味着我们将元数据作为数据的一部分进行存储。

创建 DocType 后,Frappe 可以立即提供许多开箱即用的功能。如果您访问 /app/todo,您将被路由到 Desk 中的列表视图。

ToDo 列表

同样,您可以在路由 /app/todo/000001 处获得表单视图。该表单用于创建新文档并查看它们。

ToDo 表单

站点

Frappe 是一个多租户平台,每个租户被称为一个“站点”。每个站点都有自己独立的数据库。站点位于名为 sites 的目录中,该目录在执行 bench 命令时被视为当前工作目录。

站点目录

站点目录 frappe-bench/sites 存放着此 bench 的所有站点。该目录还包含一些其他文件和目录,下面将逐一说明。

apps.txt

此文件包含 Frappe 应用的列表。一个应用必须先在此文件中列出,才能被安装到站点上。当运行 bench get-app 命令或 bench new-app 命令时,该文件会自动更新。

common_site_config.json

所有站点通用的配置可以放在此文件中。了解更多关于站点配置的信息。

assets

assets 目录包含需要提供给客户端浏览器使用的文件,通常包括 *.js、*.css 和图片文件。该目录通过 bench build 命令自动生成。在生产环境中,此目录由 Nginx 提供服务。

创建新站点

要创建新站点,请在 frappe-bench 目录下运行以下命令:

$ bench new-site mysite.localhost

Installing frappe...
Updating DocTypes for frappe        : [========================================]
Updating country info               : [========================================]
*** Scheduler is disabled ***

现在,mysite.local 目录将在 sites 目录中被创建。

目录结构

sites/mysite.localhost
├── locks
├── private
│   ├── backups
│   └── files
├── public
│   └── files
├── site_config.json
└── task-logs

locks

此目录供调度器使用,通过文件锁机制来同步各种任务。

private

此目录包含需要身份验证才能访问的文件,例如私有文件和备份。可以通过 URL:/private/files/private-file.png 访问这些文件。

public

此目录包含可公开访问的文件。可以通过 URL:/files/public-file.png 访问这些文件。

site_config.json

此文件包含站点特定的配置信息。

站点配置

每个站点目录下都有一个名为 site_config.json 的文件,用于存储该站点特定的配置。这些配置值会以字典的形式保存在 frappe.conf 局部变量中。

site_config.json 示例:

{
    "db_name": "test_frappe",
    "db_password": "test_frappe",
    "admin_password": "admin",
}

要了解更多关于管理站点或 Bench 级别配置的信息,请查阅这份综合文档。

站点解析

在处理 HTTP 请求时,系统会根据以下条件自动选择一个站点:

  • HTTP 请求中的 Host 头信息与某个站点匹配
  • HTTP 请求中的 X-Frappe-Site-Name 头信息与某个站点匹配

也可以通过以下命令启动开发服务器,强制其服务于特定站点:

bench --site mysite.localhost serve

将某个站点设置为当前站点

要强制将某个站点设为默认站点,请运行以下命令:

bench use mysite.localhost

运行此命令后,执行站点特定命令时无需再添加 --site 参数。

例如,无需运行:

bench --site mysite.localhost migrate

只需运行:

bench migrate

应用

Frappe 应用是一个使用 Frappe 框架的 Python 包。Frappe 应用位于
apps 目录下的 frappe-bench 目录中。

默认应用 frappe 是一个 Frappe 应用,它充当所有应用的基础框架。
每个 Frappe 应用都必须在 apps.txt 中有一个条目。

创建应用

Frappe 自带一个新应用的模板。要创建新应用,请在 frappe-bench 目录下
运行以下命令。

$ bench new-app custom_app
INFO:bench.app:creating new app custom_app
App Title (default: Custom App):
App Description: Custom Frappe App
App Publisher: John Doe
App Email: [email protected]
App Icon (default 'octicon octicon-file-directory'):
App Color (default 'grey'):
App License (default 'MIT'):
'custom_app' created at /Users/johndoe/frappe-bench/apps/custom_app
INFO:bench.app:installing custom_app
INFO:bench.utils:./env/bin/pip install -q -e ./apps/custom_app

现在,custom_app 目录将在 apps 目录中创建。它
也会被添加到 apps.txt 中。

目录结构

应用的目录结构大致如下:

apps/custom_app
├── MANIFEST.in
├── README.md
├── custom_app
│ ├── __init__.py
│ ├── config
│ │ ├── __init__.py
│ │ ├── desktop.py
│ │ └── docs.py
│ ├── custom_app
│ │ └── __init__.py
│ ├── hooks.py
│ ├── modules.txt
│ ├── patches.txt
│ ├── public
│ │ ├── css
│ │ └── js
│ ├── templates
│ │ ├── __init__.py
│ │ └── includes
│ └── www
├── license.txt
├── requirements.txt
├── dev-requirements.txt
├── package.json
└── setup.py

requirements.txt

此文件存储 Python 依赖项列表。安装此应用时,
其依赖项也会一并安装。

dev-requirements.txt [可选]

此文件存储 Python 开发依赖项列表。此文件的语法与
requirements.txt 相同。如果启用了开发者模式,那么
安装应用时也会安装其开发依赖项。

package.json

此文件用于跟踪 Node 依赖项。在此处了解更多信息。

customapp

这是存储源文件的目录。

customapp/customapp

当您创建新应用时,会在应用内部创建一个同名的模块。
此目录即对应于该模块。

customapp/hooks.py

此文件用于挂钩 Frappe 事件,并扩展或覆盖 Frappe 的
标准行为。

了解更多关于 hooks 的信息。

customapp/modules.txt

每个 Frappe 应用都组织为不同的模块。每个 DocType 都属于某个
模块。这些模块都列在此文件中。

了解更多关于模块的信息。

customapp/patches.txt

此文件用于存储数据库迁移过程中运行的补丁引用。
这些补丁按顺序运行,并且每个补丁只运行一次。

了解更多关于数据库迁移的信息。

customapp/public

public 文件夹是一个静态文件夹,在生产环境中可以由 nginx 提供服务。
放在这里的文件可以通过 URL /assets/custom_app/**/* 访问。

例如,文件 public/img/logo.png 可以通过 URL
/assets/custom_app/img/logo.png 访问。

此文件夹用于存储直接在客户端使用的静态资源,
如 JS、CSS 和图片。

customapp/templates

templates 文件夹用于编写和管理 Jinja 模板。您可以按照
任何方式组织它们。当您在 Jinja 模板中使用它们时,
此目录会被直接扫描。

例如,当您包含一个局部模板 {% include "templates/navbar/navbar.html" %} 时,
它会首先扫描此目录,然后回退到其他应用。

customapp/www

此目录中的文件直接映射到门户页面,URL 与
目录结构相匹配。

了解更多关于门户页面的信息。

将应用安装到站点

要使用应用,必须将其安装到站点上。将应用安装到站点意味着
将应用捆绑的模型创建到站点中,也就是说,
在站点数据库中创建数据库表。

要将应用安装到站点,请运行以下命令:

$ bench --site site_name install-app custom_app

Installing custom_app...

要检查应用是否安装正确,请运行以下命令:

$ bench --site site_name list-apps
frappe
custom_app

目录结构

当你初始化一个新的 frappe-bench 目录时,你会得到一个类似如下的目录结构:

.
├── apps
 ├── frappe
├── config
 ├── redis_cache.conf
 ├── redis_queue.conf
 └── redis_socketio.conf
├── env
├── logs
├── Procfile
└── sites
 ├── apps.txt
 ├── assets
 ├── common_site_config.json
 └── site1.local
 ├── private
 ├── public
 └── site_config.json

apps(应用)

frappe 应用和其他基于 frappe 的应用都存放在此目录中。当你运行 bench new-app app_name 命令时,应用会在此目录中被初始化。你的自定义应用也存放在这里,你应该在此处进行编辑和开发。

了解更多关于应用的信息。

sites(站点)

站点从此目录中提供服务。当你运行 bench new-site site_name 命令时,站点会在此目录中被创建。站点根据其目录名称进行区分。

了解更多关于站点的信息。

logs(日志)

此目录用于存放来自各种进程的日志文件。每个日志文件根据其来源进程进行命名。

config(配置)

Frappe 使用 3 个 Redis 实例来管理缓存、任务队列和 socketio 通信。所有这些配置都存放在此目录中。

env(环境)

Python 虚拟环境存放在此目录中。基于 Frappe 的应用和 Python 包依赖都安装在这里。

Procfile(进程文件)

Frappe 使用基于 Procfile 的进程管理方式。默认的 Procfile 内容如下所示:

redis_cache: redis-server config/redis_cache.conf
redis_socketio: redis-server config/redis_socketio.conf
redis_queue: redis-server config/redis_queue.conf
web: bench serve --port 8000

socketio: /usr/bin/node apps/frappe/socketio.js

watch: bench watch

schedule: bench schedule
worker_short: bench worker --queue short --quiet
worker_long: bench worker --queue long --quiet
worker_default: bench worker --queue default --quiet

让我们看看每个进程的用途。

redis_cache:

用于内存缓存的 Redis。

redis_socketio:

用作 websocketio 进程之间实时通信的发布/订阅(pub/sub)Redis。

redis_queue:

用于管理后台任务队列的 Redis。

web:

基于 Werkzeug 的 Python Web 服务器。

socketio:

用于与浏览器建立 socketio 连接以实现实时通信的 Node 服务器。

watch:

使用 Rollup 打包 JS/CSS 资源的 Node 服务器。它也会在文件变更时重新构建文件。

schedule:

使用 Python RQ 的作业调度器。

worker_short:

超时时间(短)为 300 秒的 Python 工作进程。

worker_long:

超时时间(长)为 1500 秒的 Python 工作进程。

worker_default:

超时时间为 300 秒的 Python 工作进程。