Controller.docs — Accès statique aux documentsCette API sera disponible à partir de Dodock v6 (branche develop). Elle n'est pas disponible sur la branche v5.
Lors du développement d'une application sur Dodock, vous avez toujours pu récupérer ou créer des documents via les fonctions génériques frappe.get_doc, frappe.new_doc, etc.
Dodock introduit désormais une alternative typée et statique : la collection Controller.docs, accessible directement depuis la classe Python d'un Doctype.
Cette approche présente plusieurs avantages pour les développeurs :
La classe controller du Doctype doit déclarer son nom de Doctype via l'attribut _DOCTYPE_NAME :
from frappe.model.document import Document
class ToDo(Document):
_DOCTYPE_NAME = "ToDo"
Cet attribut est automatiquement présent sur les controllers générés par Dodock à partir de cette version.
| Ancienne API (toujours disponible) | Nouvelle API Controller.docs | Description |
|---|---|---|
frappe.get_doc("ToDo", "T-001") | ToDo.docs.get("T-001") | Récupérer un document par son nom |
frappe.get_last_doc("ToDo") | ToDo.docs.last() | Récupérer le dernier document |
frappe.get_doc("ToDo", {"reference_doc": "ABC"}) | ToDo.docs.last({"reference_doc": "ABC"}) | Récupérer un document par filtre |
frappe.get_docs("ToDo", {"status": "Open"}) | ToDo.docs.filter({"status": "Open"}) | Récupérer plusieurs documents |
frappe.new_doc("ToDo", {"status": "Open"}) | ToDo.docs.new(status="Open") | Créer un nouveau document |
frappe.get_cached_doc("ToDo", "T-001") | ToDo.docs.get("T-001", cached=True) | Récupérer depuis le cache Redis |
frappe.get_lazy_doc("ToDo", "T-001") | ToDo.docs.get("T-001", lazy=True) | Récupérer en mode lazy |
frappe.delete_doc("ToDo", "T-001") | ToDo.docs.get("T-001").delete() | Supprimer un document |
frappe.rename_doc("ToDo", "T-001", "T-002") | ToDo.docs.get("T-001").rename("T-002") | Renommer un document |
:::
L'ancienne API (frappe.get_doc, frappe.new_doc, etc.) reste entièrement disponible et recommandée lorsque le Doctype est dynamique (inconnu à l'avance au moment de l'écriture du code).
:::
from frappe.desk.doctype.todo.todo import ToDo
todo = ToDo.docs.get("T-001")
print(todo.description)
from frappe.desk.doctype.todo.todo import ToDo
nouvel_element = ToDo.docs.new(
description="Relancer Maison Verte SARL",
status="Open",
assigned_by="administrateur@example.com",
)
nouvel_element.insert()
from frappe.desk.doctype.todo.todo import ToDo
todos_ouverts = ToDo.docs.filter({"status": "Open"})
for todo in todos_ouverts:
print(todo.name, todo.description)
from frappe.desk.doctype.todo.todo import ToDo
dernier_todo = ToDo.docs.last()
print(dernier_todo.name)
Utile pour les lectures fréquentes sans modification :
from frappe.desk.doctype.todo.todo import ToDo
todo_cache = ToDo.docs.get("T-001", cached=True)
from frappe.desk.doctype.todo.todo import ToDo
ToDo.docs.get("T-001").rename("T-002")
from frappe.desk.doctype.todo.todo import ToDo
ToDo.docs.get("T-001").delete()
Les chemins d'import vers les controllers peuvent être longs. Pour les modules comportant de nombreux Doctypes, vous pouvez exposer les classes dans le fichier __init__.py du dossier doctype :
# monapp/monmodule/doctype/__init__.py
from .mon_doctype.mon_doctype import MonDoctype
Ce qui permet d'écrire :
from monapp.monmodule.doctype import MonDoctype
::: Cette convention est optionnelle. Évaluez son intérêt selon la taille de votre module pour éviter les conflits de noms de symboles. :::
_DOCTYPE_NAME sur votre controllerPour que Controller.docs fonctionne, chaque classe doit déclarer _DOCTYPE_NAME. Sur les Doctypes existants, ajoutez simplement l'attribut de classe :
from frappe.model.document import Document
class CommandeClient(Document):
_DOCTYPE_NAME = "Commande Client"
Sans cet attribut, l'accès à .docs lèvera une erreur explicite au moment de l'exécution.
L'ancienne API reste la bonne solution dans les cas suivants :