# 文档API
文档是DocType的一个实例。它派生自frappe.model.Document类,代表数据库表中的单个记录。
# frappe.get_doc
frappe.get_doc(doctype, name)
通过doctype和name标识的记录返回一个文档对象。如果没有找到文档,将引发DoesNotExistError。如果doctype是一个单一DocType,则不需要name。
# 获取现有文档
doc = frappe.get_doc('Task', 'TASK00002')
doc.title = 'Test'
doc.save()
# 获取单一DocType
doc = frappe.get_doc('System Settings')
doc.timezone # Asia/Kolkata
2
3
4
5
6
7
8
frappe.get_doc(dict)
返回一个在内存中的新文档对象,该对象尚未存在于数据库中。
# 创建新文档
doc = frappe.get_doc({
'doctype': 'Task',
'title': 'New Task'
})
doc.insert()
2
3
4
5
6
frappe.get_doc(doctype={document_type}, key1 = value1, key2 = value2, ...)
返回一个在内存中的新文档对象,该对象尚未存在于数据库中。
# 使用关键字参数创建新对象
user = frappe.get_doc(doctype='User', email_id='test@example.com')
user.insert()
2
3
# frappe.get_last_doc
frappe.get_last_doc(doctype, filters, order_by)
返回在提到的doctype下创建的最后一个文档对象。
# 获取最后创建的任务
task = frappe.get_last_doc('Task')
2
您也可以指定过滤器来细化结果。例如,您可以通过添加过滤器来检索最后一个已取消的任务。
# 获取最后一个已取消的任务
task = frappe.get_last_doc('Task', filters={"status": "Cancelled"})
2
默认情况下,order_by参数设置为creation desc,但这个值可以被覆盖,以使用其他非标准字段来达到相同的目的。例如,您有一个字段timestamp在任务DocType下,它跟踪的是它被批准或被标记为有效而不是创建的时间。
# 基于非标准字段获取最后创建的任务
task = frappe.get_last_doc('Task', filters={"Status": "Cancelled"}, order_by="timestamp desc")
2
或者,您可以选择完全反对这一切,并且作为玩笑的一部分将其改为"creation asc"来检索第一个文档。
# frappe.get_cached_doc
类似于frappe.get_doc,但会在访问数据库之前先在缓存中查找文档。
# frappe.new_doc
frappe.new_doc(doctype)
创建新文档的另一种方式。
# 创建新文档
doc = frappe.new_doc('Task')
doc.title = 'New Task 2'
doc.insert()
2
3
4
# frappe.delete_doc
frappe.delete_doc(doctype, name)
从数据库中删除记录及其子记录。同时删除与之关联的其他文档,如通信、评论等。
frappe.delete_doc('Task', 'TASK00002')
# frappe.rename_doc
frappe.rename_doc(doctype, old_name, new_name, merge=False)
将文档的name(主键)从old_name重命名为new_name。如果merge是True并且存在一个记录new_name,则会与该记录合并。
frappe.rename_doc('Task', 'TASK00002', 'TASK00003')
只有在DocType表单中设置了允许重命名时,重命名才能起作用。
# frappe.get_meta
frappe.get_meta(doctype)
返回doctype的元信息。这也将应用自定义字段和属性设置器。
meta = frappe.get_meta('Task')
meta.has_field('status') # True
meta.get_custom_fields() # [field1, field2, ..]
2
3
要获取DocType的原始文档(不含自定义字段和属性设置器),请使用frappe.get_doc('DocType', doctype_name)
# 文档方法
这一节列出了doc对象上可用的常见方法。
# doc.insert
此方法将新文档插入数据库表中。它将检查用户权限,并在控制器中编写时执行before_insert、validate、on_update、after_insert方法。
它有一些逃生舱口,可以用来跳过下面解释的某些检查。
doc.insert(
ignore_permissions=True, # 在插入期间忽略写入权限
ignore_links=True, # 忽略文档中的链接验证
ignore_if_duplicate=True, # 如果抛出DuplicateEntryError,则不插入
ignore_mandatory=True # 即使未设置必填字段也插入
)
2
3
4
5
6
# doc.save
此方法保存现有文档的更改。这将在更新前检查用户权限,并在更新后执行validate和on_update。
doc.save(
ignore_permissions=True, # 在插入期间忽略写入权限
ignore_version=True # 不创建版本记录
)
2
3
4
# doc.delete
从数据库表中删除文档记录。此方法是frappe.delete_doc的别名。
doc.delete()
# doc.get_doc_before_save
将在更改之前返回文档的版本。您可以使用它来比较上次版本有什么变化。
old_doc = doc.get_doc_before_save()
if old_doc.price != doc.price:
# 价格变动了
pass
2
3
4
# doc.has_value_changed
如果给定字段的值在保存前后发生了变化,将返回True。
price_changed = doc.has_value_changed("price")
if price_changed:
pass
2
3
4
# doc.reload
将从数据库获取最新值并更新文档状态。
当您使用文档时,可能会发生代码的其他部分直接在数据库中更新某些字段的值的情况。在这种情况下,您可以使用此方法重新加载文档。
doc.reload()
# doc.check_permission
如果没有提供permtype的权限,则抛出异常。
doc.check_permission(permtype='write') # 如果没有写入权限则抛出异常
# doc.get_title
根据title_field或名为title或name的字段获取文档标题。
title = doc.get_title()
# doc.notify_update
发布实时事件,以指示文档已被修改。客户端事件处理程序通过更新表单来响应此事件。
doc.notify_update()
# doc.db_set
直接在数据库中设置文档字段的值,并更新修改时间戳。
此方法不会触发控制器验证,应非常谨慎地使用。
# 在数据库中更新值,更新修改时间戳
doc.db_set('price', 2300)
# 在数据库中更新值,将触发doc.notify_update()
doc.db_set('price', 2300, notify=True)
# 在数据库中更新值,也将运行frappe.db.commit()
doc.db_set('price', 2300, commit=True)
# 在数据库中更新值,不更新修改时间戳
doc.db_set('price', 2300, update_modified=False)
2
3
4
5
6
7
8
9
10
11
# doc.append
向子表中添加一个新项目。
doc.append("childtable", {
"child_table_field": "value",
"child_table_int_field": 0,
...
})
2
3
4
5
# doc.get_url
返回此文档的Desk URL。例如:/app/task/TASK00002
url = doc.get_url()
# doc.add_comment
对此文档添加评论。将在表单视图的时间线中显示。
# 添加简单评论
doc.add_comment('Comment', text='Test Comment')
# 添加编辑类型的评论
doc.add_comment('Edit', 'Values changed')
# 添加共享类型的评论
doc.add_comment("Shared", "{0} shared this document with everyone".format(user))
2
3
4
5
6
7
8
# doc.add_seen
将给定/当前用户添加到已查看此文档的用户列表中。将更新表中的_seen列。它存储为JSON数组。
# 将john添加到查看列表
doc.add_seen('john@doe.com')
# 将会话用户添加到查看列表
doc.add_seen()
2
3
4
5
只有当DocType中启用了Track Seen时,此功能才有效。
# doc.add_viewed
当用户查看文档即打开表单时,添加查看日志。
# 由john添加查看日志
doc.add_viewed('john@doe.com')
# 由会话用户添加查看日志
doc.add_viewed()
2
3
4
5
只有当DocType中启用了Track Views时,此功能才有效。
# doc.add_tag
给文档添加标签。标签通常用于过滤和分组文档。
# 添加标签
doc.add_tag('developer')
doc.add_tag('frontend')
2
3
# doc.get_tags
返回与特定文档关联的标签列表。
# 获取所有标签
doc.get_tags()
2
# doc.run_method
如果在控制器中定义了方法,则运行该方法,如果定义了钩子,则也会触发。
doc.run_method('validate')
# doc.queue_action
在后台运行控制器方法。如果该方法有一个内部函数,比如submit的_submit,它将调用那个方法。
doc.queue_action('send_emails', emails=email_list, message='Howdy')
# doc.get_children()
仅在树形DocTypes(继承自
NestedSet)上可用。
返回一个生成器,为每个子记录产生一个NestedSet实例。
for child_doc in doc.get_children():
print(child_doc.name)
2
3
也可以递归应用:
for child_doc in doc.get_children():
print(child_doc.name)
for grandchild_doc in child_doc.get_children():
print(grandchild_doc.name)
2
3
4
# doc.get_parent()
仅在树形DocTypes(继承自
NestedSet)上可用。
返回父记录的NestedSet实例。
parent_doc = doc.get_parent()
grandparent_doc = parent_doc.get_parent()
2
# doc.db_insert()
将文档序列化并插入数据库。警告:这绕过了所有可能需要在插入前和插入后运行的验证和控制器方法。如果有疑问,请使用doc.insert()代替。
doc = frappe.get_doc(doctype="Controller", data="")
doc.db_insert()
2
# doc.db_update()
将文档序列化并更新数据库。警告:这绕过了所有可能需要在更新前和更新后运行的验证和控制器方法。如果有疑问,请使用doc.save()代替。
doc = frappe.get_last_doc("User")
doc.last_active = now()
doc.db_update()
2
3
← 自定义文档类型