Frappe Framework
API Document
Toutes les fonctions et méthodes pour manipuler un Document Frappe en Python : chargement, création, enregistrement, suppression, renommage, commentaires, tags et arborescences.
Qu’est-ce qu’un Document
Un Document est une instance d’un DocType. Il dérive de la classe frappe.model.Document et représente un enregistrement unique dans la table de la base de données.
Fonctions du module frappe
frappe.get_doc
frappe.get_doc(doctype, name)
Renvoie l’objet Document de l’enregistrement identifié par doctype et name. Si aucun document n’est trouvé, une exception DoesNotExistError est levée. Si doctype est un DocType Single, name n’est pas nécessaire.
# 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/Kolkatafrappe.get_doc(dict)
Renvoie un nouvel objet Document en mémoire, qui n’existe pas encore dans la base de données.
# 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, ...)
Renvoie également un nouvel objet Document en mémoire, qui n’existe pas encore dans la base de données.
# 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)
Renvoie le dernier objet Document créé pour le doctype indiqué.
# get the last Task created
task = frappe.get_last_doc('Task')Vous pouvez affiner le résultat avec des filtres. Par exemple, pour récupérer la dernière tâche annulée :
# get the last available Cancelled Task
task = frappe.get_last_doc('Task', filters={"status": "Cancelled"})Par défaut, l’argument order_by vaut creation desc, mais vous pouvez le remplacer par un autre champ, non standard, qui joue le même rôle. Par exemple, un champ timestamp du DocType Task qui enregistre la date d’approbation ou de validation plutôt que la date de création.
# get the last Task created based on a non-standard field
task = frappe.get_last_doc('Task', filters={"Status": "Cancelled"}, order_by="timestamp desc")Vous pouvez aussi, comme le note la source avec humour, prendre le contre-pied complet et passer creation asc pour obtenir le premier document au lieu du dernier.
frappe.get_cached_doc
Semblable à frappe.get_doc, mais cherche d’abord le document dans le cache avant d’interroger la base de données.
frappe.new_doc
frappe.new_doc(doctype)
Autre façon de créer un nouveau Document.
# create a new document
doc = frappe.new_doc('Task')
doc.title = 'New Task 2'
doc.insert()frappe.delete_doc
frappe.delete_doc(doctype, name)
Supprime l’enregistrement et ses enfants de la base de données. Supprime aussi les autres documents qui lui sont liés, comme les Communication, les commentaires, etc.
frappe.delete_doc('Task', 'TASK00002')frappe.rename_doc
frappe.rename_doc(doctype, old_name, new_name, merge=False)
Renomme le name (clé primaire) d’un document de old_name vers new_name. Si merge vaut True et qu’un enregistrement nommé new_name existe déjà, les deux enregistrements sont fusionnés.
frappe.rename_doc('Task', 'TASK00002', 'TASK00003')À retenir
Le renommage ne fonctionne que si l’option Allow Rename est cochée dans le formulaire du DocType.
frappe.get_meta
frappe.get_meta(doctype)
Renvoie les métadonnées du doctype. Les champs personnalisés (Custom Field) et les Property Setter y sont appliqués.
meta = frappe.get_meta('Task')
meta.has_field('status') # True
meta.get_custom_fields() # [field1, field2, ..]Pour obtenir le document DocType d’origine (sans champs personnalisés ni Property Setter), utilisez frappe.get_doc('DocType', doctype_name).
frappe.only_for
frappe.only_for(roles, message=False)
Lève frappe.PermissionError si l’utilisateur courant ne possède aucun des rôles autorisés.
Si l’utilisateur courant est Administrator, la vérification est ignorée.
# restrict action to System Manager role
frappe.only_for("System Manager")Vous pouvez aussi autoriser plusieurs rôles :
# 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)
Renvoie une liste d’objets Document. Utilisez as_iterator=True pour récupérer les enregistrements par lots et mieux maîtriser la mémoire.
| Paramètre | Valeur par défaut | Rôle |
|---|---|---|
doctype | — | DocType à lire. |
filters | — | Filtres appliqués à la requête. |
chunk_size | 1000 | Taille des lots lus. |
limit | None | Nombre maximal de documents. |
limit_start | 0 | Décalage de départ. |
order_by | "creation asc" | Ordre de tri. |
as_iterator | False | Si True, renvoie un itérateur qui charge les documents par lots. |
# 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 methodMéthodes du Document
Cette section liste les méthodes courantes disponibles sur l’objet doc.
doc.insert
Insère un nouveau document dans la table de la base de données. La méthode vérifie les permissions de l’utilisateur et exécute les méthodes before_insert, validate, on_update et after_insert si elles sont définies dans le contrôleur.
Elle propose quelques échappatoires pour ignorer certaines vérifications :
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
)| Option | Effet |
|---|---|
ignore_permissions | Ignore les permissions d’écriture lors de l’insertion. |
ignore_links | Ignore la validation des champs de lien (Link) du document. |
ignore_if_duplicate | N’insère pas si une DuplicateEntryError est levée. |
ignore_mandatory | Insère même si des champs obligatoires ne sont pas renseignés. |
doc.save
Enregistre les modifications d’un document existant. La méthode vérifie les permissions de l’utilisateur, exécute validate avant la mise à jour et on_update après.
doc.save(
ignore_permissions=True, # ignore write permissions during insert
ignore_version=True # do not create a version record
)| Option | Effet |
|---|---|
ignore_permissions | Ignore les permissions d’écriture. |
ignore_version | Ne crée pas d’enregistrement de version (Version). |
doc.delete
Supprime l’enregistrement du document dans la table de la base de données. Cette méthode est un alias de frappe.delete_doc.
doc.delete()doc.get_doc_before_save
Renvoie la version du document telle qu’elle était avant les modifications. Utile pour comparer ce qui a changé par rapport à la dernière version.
old_doc = doc.get_doc_before_save()
if old_doc.price != doc.price:
# price changed
passdoc.has_value_changed
Renvoie True si la valeur du champ indiqué a changé entre l’état avant et après enregistrement.
price_changed = doc.has_value_changed("price")
if price_changed:
passdoc.reload
Recharge les dernières valeurs depuis la base de données et met à jour l’état du document.
Il arrive, pendant que vous travaillez sur un document, qu’une autre partie du code modifie directement la valeur d’un champ en base. Cette méthode permet alors de recharger le document.
doc.reload()doc.check_permission
Lève une exception si l’utilisateur courant n’a pas la permission du type indiqué (permtype).
doc.check_permission(permtype='write') # throws if no write permissiondoc.get_title
Renvoie le titre du document d’après title_field, ou d’après le champ nommé title ou name.
title = doc.get_title()doc.notify_update
Publie un événement temps réel pour signaler que le document a été modifié. Les gestionnaires côté client réagissent en mettant à jour le formulaire.
doc.notify_update()doc.db_set
Définit la valeur d’un champ du document directement dans la base de données et met à jour l’horodatage modified.
Attention
Cette méthode ne déclenche pas les validations du contrôleur ; elle doit être utilisée avec beaucoup de prudence.
# 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)| Option | Effet |
|---|---|
notify=True | Déclenche aussi doc.notify_update(). |
commit=True | Exécute aussi frappe.db.commit(). |
update_modified=False | Ne met pas à jour l’horodatage modified. |
doc.append
Ajoute une nouvelle ligne à une table enfant (Child Table).
doc.append("childtable", {
"child_table_field": "value",
"child_table_int_field": 0,
...
})doc.get_url
Renvoie l’URL du document dans le bureau (Desk), par exemple /app/task/TASK00002.
url = doc.get_url()doc.add_comment
Ajoute un commentaire au document. Il apparaît dans la chronologie (timeline) de la vue formulaire.
# 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
Ajoute l’utilisateur indiqué (ou l’utilisateur courant) à la liste des utilisateurs qui ont vu ce document. La colonne _seen de la table est mise à jour ; elle est stockée sous forme de tableau JSON.
# add john to list of seen
doc.add_seen('[email protected]')
# add session user to list of seen
doc.add_seen()À retenir
Ne fonctionne que si Track Seen est activé dans le DocType.
doc.add_viewed
Ajoute une entrée au journal des vues quand un utilisateur consulte le document, c’est-à-dire ouvre le formulaire.
# add a view log by john
doc.add_viewed('[email protected]')
# add a view log by session user
doc.add_viewed()À retenir
Ne fonctionne que si Track Views est activé dans le DocType.
doc.add_tag
Ajoute une étiquette (Tag) au document. Les étiquettes servent généralement à filtrer et regrouper les documents.
# add tags
doc.add_tag('developer')
doc.add_tag('frontend')doc.get_tags
Renvoie la liste des étiquettes associées au document.
# get all tags
doc.get_tags()doc.run_method
Exécute la méthode si elle est définie dans le contrôleur, et déclenche aussi les hooks correspondants s’il y en a.
doc.run_method('validate')doc.queue_action
Exécute une méthode du contrôleur en arrière-plan. Si la méthode possède une fonction interne, comme _submit pour submit, c’est cette fonction interne qui est appelée.
doc.queue_action('send_emails', emails=email_list, message='Howdy')doc.get_children()
À retenir
Disponible uniquement sur les DocTypes arborescents (qui héritent de NestedSet).
Renvoie un générateur qui produit une instance de NestedSet pour chaque enregistrement enfant.
for child_doc in doc.get_children():
print(child_doc.name)L’appel peut être récursif :
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()
À retenir
Disponible uniquement sur les DocTypes arborescents (qui héritent de NestedSet).
Renvoie une instance de NestedSet pour l’enregistrement parent.
parent_doc = doc.get_parent()
grandparent_doc = parent_doc.get_parent()doc.db_insert()
Sérialise et insère un document dans la base de données.
Attention
Cette méthode contourne toutes les validations et méthodes du contrôleur qui devraient s’exécuter avant et après l’insertion. En cas de doute, utilisez plutôt doc.insert().
doc = frappe.get_doc(doctype="Controller", data="")
doc.db_insert()doc.db_update()
Sérialise et met à jour un document dans la base de données.
Attention
Cette méthode contourne toutes les validations et méthodes du contrôleur qui devraient s’exécuter avant et après la mise à jour. En cas de doute, utilisez plutôt doc.save().
doc = frappe.get_last_doc("User")
doc.last_active = now()
doc.db_update()