文档接口

文档是 DocType 的一个实例。它派生自 frappe.model.Document 类,并代表数据库表中的一条记录。

frappe.get_doc

frappe.get_doc(doctype, name)

返回由 doctypename 标识的记录对应的文档对象。如果未找到文档,则会引发 DoesNotExistError 异常。如果 doctype 是单例 DocType,则不需要 name

# get an existing document
doc = frappe.get_doc('Task', 'TASK00002')
doc.title = 'Test'
doc.save()

# get a single doctype
doc = frappe.get_doc('System Settings')
doc.timezone # Asia/Kolkata

frappe.get_doc(dict)

返回一个内存中新的文档对象,该对象在数据库中尚不存在。

# create a new document
doc = frappe.get_doc({
    'doctype': 'Task',
    'title': 'New Task'
})
doc.insert()

frappe.get_doc(doctype={document_type}, key1 = value1, key2 = value2, ...)

返回一个内存中新的文档对象,该对象在数据库中尚不存在。

# create new object with keyword arguments
user = frappe.get_doc(doctype='User', email_id='[email protected]')
user.insert()

frappe.get_last_doc

frappe.get_last_doc(doctype, filters, order_by)

返回在指定 doctype 下创建的最后一个文档对象。

# get the last Task created
task = frappe.get_last_doc('Task')

您还可以指定过滤器来优化结果。例如,您可以通过添加过滤器来检索最后一个已取消的任务。

# get the last available Cancelled Task
task = frappe.get_last_doc('Task', filters={"status": "Cancelled"})

默认情况下,order_by 参数设置为 creation desc,但可以覆盖此值以使用其他可以达到相同目的的非标准字段。例如,您在 任务 DocType 下有一个字段 timestamp,它记录的是任务被批准或标记为有效的时间,而不是创建时间。

# get the last Task created based on a non-standard field
task = frappe.get_last_doc('Task', filters={"Status": "Cancelled"}, order_by="timestamp desc")

或者,您也可以完全反其道而行之,作为玩笑将其更改为“creation asc”来检索第一个文档。

frappe.get_cached_doc

类似于 frappe.get_doc,但会先查询缓存中的文档,然后再访问数据库。

frappe.new_doc

frappe.new_doc(doctype)

创建新文档的另一种方式。

# create a new document
doc = frappe.new_doc('Task')
doc.title = 'New Task 2'
doc.insert()

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。如果 mergeTrue 且存在 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, ..]

要获取 DocType 的原始文档(不含自定义字段和属性设置器),请使用 frappe.get_doc('DocType', doctype_name)

frappe.only_for

frappe.only_for(roles, message=False)

如果当前用户没有任何允许的角色,则引发 frappe.PermissionError 异常。

如果当前用户是 Administrator,则跳过权限检查。

# restrict action to System Manager role
frappe.only_for("System Manager")

您也可以允许多个角色:

# allow multiple roles
frappe.only_for(["System Manager", "Accounts Manager"])

frappe.get_docs

frappe.get_docs(doctype, filters, *, chunk_size=1000, limit=None, limit_start=0, order_by="creation asc", as_iterator=False)

返回文档对象列表。使用 as_iterator=True 分块获取记录,以便更好地管理内存。

# Fetch specific documents with child tables
tasks = frappe.get_docs('Task', filters={'status': 'Open'}, limit=10)

for task in tasks:
    task.status = "Closed"
    task.save()

# Efficiently iterate through large datasets
leads = frappe.get_docs('Lead', as_iterator=True, chunk_size=500)

for lead in leads:
    lead.process_lead() # Custom controller method

文档方法

本节列出了 doc 对象上可用的常用方法。

doc.insert

此方法将新文档插入数据库表。它会检查用户权限,如果控制器中编写了 before_insertvalidateon_updateafter_insert 方法,则会执行这些方法。

它有一些“逃生舱”机制,可用于跳过下面说明的某些检查。

doc.insert(
    ignore_permissions=True, # ignore write permissions during insert
    ignore_links=True, # ignore Link validation in the document
    ignore_if_duplicate=True, # dont insert if DuplicateEntryError is thrown
    ignore_mandatory=True # insert even if mandatory fields are not set
)

doc.save

此方法保存对现有文档的更改。它会检查用户权限,并在更新前执行 validate,在更新值后执行 on_update

doc.save(
    ignore_permissions=True, # ignore write permissions during insert
    ignore_version=True # do not create a version record
)

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:
    # price changed
    pass

doc.has_value_changed

如果给定字段的值在保存前后发生了变化,则返回 True。

price_changed = doc.has_value_changed("price")

if price_changed:
    pass

doc.reload

将从数据库获取最新值并更新文档状态。

当您在处理文档时,可能代码的其他部分会直接更新数据库中某个字段的值。在这种情况下,您可以使用此方法重新加载文档。

doc.reload()

doc.check_permission

如果当前用户没有所提供权限类型的权限,则抛出异常。

doc.check_permission(permtype='write') # throws if no write permission

doc.get_title

根据 title_field 或名为 titlename 的字段获取文档标题。

title = doc.get_title()

doc.notify_update

发布实时事件以指示文档已被修改。客户端事件处理程序通过更新表单来响应此事件。

doc.notify_update()

doc.db_set

直接在数据库中设置文档的字段值,并更新修改时间戳。

此方法不会触发控制器验证,应谨慎使用。

# updates value in database, updates the modified timestamp
doc.db_set('price', 2300)

# updates value in database, will trigger doc.notify_update()
doc.db_set('price', 2300, notify=True)

# updates value in database, will also run frappe.db.commit()
doc.db_set('price', 2300, commit=True)

# updates value in database, does not update the modified timestamp
doc.db_set('price', 2300, update_modified=False)

doc.append

向子表追加一个新项目。

doc.append("childtable", {
    "child_table_field": "value",
    "child_table_int_field": 0,
    ...
})

doc.get_url

返回此文档的 Desk URL。例如:/app/task/TASK00002

url = doc.get_url()

doc.add_comment

向此文档添加评论。评论将显示在表单视图的时间线中。

# add a simple comment
doc.add_comment('Comment', text='Test Comment')

# add a comment of type Edit
doc.add_comment('Edit', 'Values changed')

# add a comment of type Shared
doc.add_comment("Shared", "{0} shared this document with everyone".format(user))

doc.add_seen

将给定/当前用户添加到已查看此文档的用户列表中。这将更新表中的 _seen 列。该列以 JSON 数组形式存储。

# add john to list of seen
doc.add_seen('[email protected]')

# add session user to list of seen
doc.add_seen()

此功能仅在 DocType 中启用了 跟踪已查看 时才有效。

doc.add_viewed

当用户查看文档(即打开表单)时,添加一条查看日志。

# add a view log by john
doc.add_viewed('[email protected]')

# add a view log by session user
doc.add_viewed()

此功能仅在 DocType 中启用了 跟踪查看 时才有效。

doc.add_tag

向文档添加标签。标签通常用于筛选和分组文档。

# add tags
doc.add_tag('developer')
doc.add_tag('frontend')

doc.get_tags

返回与特定文档关联的标签列表。

# get all tags
doc.get_tags()

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()

仅适用于树形 DocType(继承自 NestedSet)。

返回一个生成器,为每个子记录生成一个 NestedSet 实例。

for child_doc in doc.get_children():
    print(child_doc.name)

它也可以递归应用:

for child_doc in doc.get_children():
    print(child_doc.name)
    for grandchild_doc in child_doc.get_children():
        print(grandchild_doc.name)

doc.get_parent()

仅适用于树形 DocType(继承自 NestedSet)。

返回父记录的 NestedSet 实例。

parent_doc = doc.get_parent()
grandparent_doc = parent_doc.get_parent()

doc.db_insert()

将文档序列化并插入数据库。警告:此操作会绕过所有验证以及插入前后可能需要运行的控制器方法。如有疑问,请改用 doc.insert()

doc = frappe.get_doc(doctype="Controller", data="")
doc.db_insert()

doc.db_update()

将文档序列化并更新到数据库。警告:此操作会绕过所有验证以及更新前后可能需要运行的控制器方法。如有疑问,请改用 doc.save()

doc = frappe.get_last_doc("User")
doc.last_active = now()
doc.db_update()