# 虚拟字段(Virtual DocField)
虚拟字段(Virtual DocField)是给定文档(或记录)的动态属性。它是一种计算属性,不存储在网站数据库中。这可以用于表示可能是其他静态文档属性函数的值。
Person Form
一个人的岁数是他们出生日期的函数,即如果你知道一个人的出生日期,你可以计算出他们的年龄。年龄也是一个连续值;它可能每年、每月、每天甚至每小时都在变化,这取决于你希望拥有的粒度类型。另一个属性是人的姓名。大多数常见的实现会有名、中间名和姓氏,而在视图中会将它们全部放在一起,如“Jon Raphael Doe”。尽管在可以轻松连接字符串的情况下,保存全名作为单独的属性可能没有太多意义。这些是虚拟字段更有意义的几个例子。
Person DocType
在这里,我们为人员添加了三个字段;两个用于存储在网站数据库中的名字和姓氏,一个利用这些数据来填充第三个字段“全名”。在这个例子中,选项字段接受相应虚拟字段的返回值。
Person DocType - DocField
我们讨论了依赖系统中属性的字段的可能性。但这可以很容易地扩展到不仅仅依赖你的DocType数据的东西。您可能还想获取多个外部服务的状态,或者你可以在这里映射的任何其他东西。
# 如何使用虚拟字段
使这工作涉及的步骤包括:
# 1. 定义一个虚拟字段
定义一个虚拟字段非常简单。只需在DocField配置下勾选“虚拟”复选框即可。虚拟字段不会在DocType的表中创建相应的列。这使得字段在表单视图中变为“只读”。
注意:除非你知道自己在做什么,否则避免将现有的DocFields设为虚拟字段。
# 2. 为字段定义一个来源
第一步只是为值添加了一个占位符。如果不添加一些代码来指定字段应该显示什么,就没有字段本身。有两种方法可以做到这一点:
- 通过扩展DocType控制器
添加一个与虚拟字段同名的Python属性应该可以做到这一点。这是最灵活的方法;你可以进行内部API请求的连锁,或者从多个数据源获取数据,没有限制。
class Person(Document):
@property
def age(self):
return frappe.utils.now_datetime() - self.creation
2
3
4
- 使用
DocField.options
这在某种程度上更加受限,因为它允许你直接从Desk编写代码。服务器脚本和文档属性中允许的实用工具可以通过这种方式访问。上述属性的等效可能如下:
frappe.utils.now_datetime() - self.creation
上述提到的Person.full_name示例使用Python的f字符串功能以类似的方式实现。
注意:对于相对较小的脚本,应该首选这种方法。使用时注意不兼容类型的错误。
# 对内部的影响
如果你熟悉Frappe世界的物理特性,这个特性将显得相当可预测。
# 后端API
DatabaseQuery方法或Database API不会返回虚拟值,因为它们不存在于网站数据库中。

# REST API
/api/method/frappe.desk.form.load.getdoc和/api/resource API使用Document.get_valid_dict,它也会计算虚拟值。这些API也用于渲染桌面表单视图。

# 数据库
在相应的DocType表中没有虚拟字段的痕迹。然而,你可能会在自定义字段、DocField表中找到相应的记录,这些表存储了DocType的元数据。
