虚拟 DocType 是 DocType 的一个功能扩展,允许开发者创建具有自定义数据源和 DocType 控制器的 DocType。其目的是在系统中定义自定义 DocType,而无需在数据库中创建表,同时利用框架提供的前端、资源 API 以及角色和权限功能。
这些虚拟 DocType 在前端的行为与普通 DocType 完全一致,对最终用户来说无法区分,但为开发者提供了对 DocType 数据源的更多控制。借助这一特性,虚拟 DocType 的数据源可以是任何内容:外部 API、辅助数据库、JSON 或 CSV 文件等。这使得开发者能够接入除 MariaDB 和 Postgres 之外的其他数据库后端,让 Frappe 框架变得更加强大!
注意:frappe.db.* 调用仅适用于站点数据库连接。您需要实现相应方法,以直接查询虚拟 DocType 所使用的数据存储。
创建虚拟 DocType
要创建虚拟 DocType,只需在创建 DocType 时勾选“虚拟 DocType”复选框即可:
创建自定义控制器
例如,以下控制器代码使用 JSON 文件作为 DocType 的数据源:
class VirtualDoctype(Document):
"""This is a virtual doctype controller for demo purposes.
- It uses a single JSON file on disk as "backend".
- Key is docname and value is the document itself.
Example:
{
"doc1": {"name": "doc1", ...}
"doc2": {"name": "doc2", ...}
}
"""
DATA_FILE = "data_file.json"
@staticmethod
def get_current_data() -> dict[str, dict]:
"""Read data from disk"""
if not os.path.exists(VirtualDoctype.DATA_FILE):
return {}
with open(VirtualDoctype.DATA_FILE) as f:
return json.load(f)
@staticmethod
def update_data(data: dict[str, dict]) -> None:
"""Flush updated data to disk"""
with open(VirtualDoctype.DATA_FILE, "w+") as data_file:
json.dump(data, data_file)
def db_insert(self, *args, **kwargs):
d = self.get_valid_dict(convert_dates_to_str=True)
data = self.get_current_data()
data[d.name] = d
self.update_data(data)
def load_from_db(self):
data = self.get_current_data()
d = data.get(self.name)
super(Document, self).__init__(d)
def db_update(self, *args, **kwargs):
# For this example insert and update are same operation,
# it might be different for you.
self.db_insert(*args, **kwargs)
def delete(self):
data = self.get_current_data()
data.pop(self.name, None)
self.update_data(data)
@staticmethod
def get_list(args):
data = VirtualDoctype.get_current_data()
return [frappe._dict(doc) for name, doc in data.items()]
@staticmethod
def get_count(args):
data = VirtualDoctype.get_current_data()
return len(data)
@staticmethod
def get_stats(args):
return {}
您可以在接口文件中了解接口要求及详细说明。要将其他数据源与虚拟 DocType 集成,您需要添加定义数据库访问方式的控制器方法。
结果
虚拟 DocType 的前端保持不变
框架定义的所有 /api/resource 方法均与虚拟 DocType 兼容。
自版本 13 起新增