Introduction
Si vous avez passé du temps à travailler dans le modèle de données Odoo, vous avez probablement rencontré des situations où vous devez afficher une valeur d'un enregistrement lié directement sur un formulaire, sans demander à l'utilisateur de cliquer pour accéder à un autre modèle. Le champ lié est la solution qu'Odoo propose de manière propre et déclarative.
Plutôt que d'écrire un champ calculé avec une méthode Python, un champ lié se contente de lire à travers une chaîne relationnelle existante et expose la valeur à la fin de celle-ci. C'est l'un des outils les plus utiles dans le guide des développeurs Odoo, et il est également accessible aux consultants d'affaires travaillant avec Odoo Studio qui ont besoin de faire ressortir des informations contextuelles sans écrire de code.
Ce guide explique ce que le champ lié stocke, comment il fonctionne dans le cadre Odoo, comment le créer et le configurer via Studio ou Python, et où il s'intègre dans les flux de travail réels des entreprises.
Quel est le champ lié dans Odoo
Dans l'ORM Odoo, un champ lié n'est pas un type de champ distinct de la même manière que Float ou Char. Au lieu de cela, c'est un raccourci qui expose un champ d'un autre modèle en suivant une chaîne de champs relationnels. Le champ lié prend le type de n'importe quel champ auquel il pointe à la fin de la chaîne.
L'exemple le plus simple : un bon de commande a un champ partner_id (un Many2one pointant vers res.partner). Un champ lié défini comme related='partner_id.country_id' exposerait directement le pays du client sur le bon de commande, sans stocker une copie séparée.
Du point de vue de l'utilisateur, un champ lié ressemble exactement à n'importe quel autre champ dans la vue de formulaire. Si le champ terminal dans la chaîne est un Char, le champ lié s'affiche comme un champ de texte. S'il s'agit d'un Many2one, il s'affiche comme un menu déroulant. S'il s'agit d'un Booléen, il montre une case à cocher. Le champ lié hérite de la présentation visuelle du champ qu'il reflète.
Par défaut, les champs liés sont en lecture seule et non stockés dans la base de données. Cela signifie qu'ils affichent toujours la valeur actuelle du dossier source, mais vous ne pouvez pas filtrer ou rechercher des dossiers en les utilisant directement dans un domaine à moins que vous ne définissiez store=True.
Dans Odoo Studio, le champ lié est disponible lors de l'ajout d'un nouveau champ à un formulaire. Vous sélectionnez un chemin relationnel existant, et Studio crée le champ avec la configuration appropriée. Cela en fait l'un des champs Odoo Studio les plus pratiques pour les consultants qui ont besoin d'enrichir des formulaires sans écrire de Python.
Comment fonctionne le champ
Lorsque Odoo lit un champ lié, il suit la chaîne de noms de champs séparés par des points. Chaque étape de la chaîne (sauf la dernière) doit être un champ relationnel : un Many2one, One2many ou Many2many. Le dernier champ de la chaîne peut être de n'importe quel type.
Voici un exemple simple d'un champ lié défini dans un module Python :
from odoo import fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
partner_country_id = fields.Many2one(
related='partner_id.country_id',
string='Pays du Client',
store=True,
)
Dans cet exemple, Odoo suit partner_id pour atteindre l'enregistrement res.partner, puis lit country_id à partir de celui-ci. Le résultat est un champ Many2one sur le bon de commande qui reflète le pays du client.
Champs Liés Stockés vs. Non Stockés
C'est la distinction la plus importante à comprendre. Par défaut, un champ lié a store=False, ce qui signifie qu'il est calculé à la volée chaque fois que l'enregistrement est lu. La valeur ne vit pas dans la table de base de données pour le modèle.
Avec store=True, Odoo écrit la valeur dans la colonne de la base de données lorsque l'enregistrement source change. Cela permet de filtrer, de regrouper et de rechercher sur le champ lié, ce qui le rend beaucoup plus utile pour les rapports et les vues en liste.
Le compromis est que les champs liés stockés consomment de l'espace dans la base de données et nécessitent un déclencheur de mise à jour chaque fois que la source change. Odoo gère cela automatiquement grâce à son système de suivi des dépendances, mais il est bon d'en être conscient pour les modèles sensibles aux performances avec de nombreux enregistrements.
Champs liés en lecture seule vs. modifiables
Par défaut, les champs liés sont en lecture seule. Ajouter readonly=False rend le champ modifiable. Lorsque l'utilisateur change la valeur, Odoo la réécrit à travers la chaîne jusqu'à l'enregistrement source. C'est un comportement puissant mais potentiellement surprenant : modifier le champ lié sur un bon de commande modifie en réalité l'enregistrement du partenaire, et non la commande elle-même.
N'utilisez des champs liés modifiables que si vous avez réellement l'intention de ce comportement d'écriture à travers. Cela peut être très utile dans certains contextes, comme un champ d'édition rapide dans une vue en liste, mais cela peut également entraîner des modifications de données non intentionnelles si les utilisateurs ne comprennent pas ce qu'ils modifient.
Attributs clés des champs
Voici les principaux paramètres que vous configurez sur un champ lié :
- related : La chaîne de noms de champs séparés par des points (par exemple,
'partner_id.country_id'). C'est le seul attribut requis. - store : Défini sur
Truepour persister la valeur dans la base de données. Permet le filtrage et le regroupement. - readonly : Défini sur
Falsepour permettre aux utilisateurs de modifier le champ, ce qui écrit à travers la source. - string : L'étiquette affichée aux utilisateurs. Par défaut, cela correspond à l'étiquette du champ terminal.
- depends : Normalement pas nécessaire puisque Odoo déduit les dépendances de la chaîne
relatedautomatiquement. Nécessaire uniquement dans des cas particuliers.
Comment cela interagit avec l'ORM Odoo
Lire un champ lié renvoie la valeur du champ terminal sur l'enregistrement lié. Si un lien dans la chaîne est vide (par exemple, partner_id n'est pas défini), le champ lié renvoie False. C'est le comportement standard de l'ORM Odoo et s'applique à tous les champs relationnels dans le modèle de données Odoo.
Les champs liés sont entièrement pris en charge dans les domaines, les vues et les rapports lorsqu'ils sont stockés. Les champs liés non stockés peuvent être affichés dans les vues de formulaire et de liste, mais ils ne peuvent pas être utilisés comme critères de filtrage dans un domaine de recherche à moins que le serveur ne les évalue en Python plutôt qu'en SQL.
Cas d'utilisation en entreprise
Les champs liés apparaissent dans presque toutes les parties d'une implémentation Odoo. Voici cinq exemples pratiques tirés de véritables flux de travail d'entreprise.
CRM et Ventes : Téléphone du client sur les commandes de vente
Une demande courante des équipes de vente est de voir le numéro de téléphone du client directement sur le formulaire de commande de vente, sans avoir à ouvrir le dossier du client séparément. Un champ lié défini comme related='partner_id.phone' sur sale.order résout cela immédiatement. Il affiche le numéro de téléphone dans le contexte, accélère les appels de vente et ne nécessite aucun effort de développement supplémentaire. Dans Odoo Studio, un consultant peut ajouter cela en moins d'une minute en utilisant l'option de champ lié.
Comptabilité : Devise de l'entreprise sur les lignes de facture
Dans les configurations Odoo multi-entreprises, les comptables ont parfois besoin d'afficher la devise de l'entreprise directement sur les lignes de facture pour plus de clarté dans les rapports. Un champ lié comme related='move_id.company_id.currency_id' enchaîne à travers deux champs Many2one pour atteindre la devise. Cette chaîne à trois niveaux est valide, bien qu'il soit généralement recommandé de garder les chaînes courtes pour des raisons de performance. Le stockage de ce champ permet de filtrer les factures par devise d'entreprise dans les rapports analytiques.
Inventaire : Catégorie de produit sur les lignes de mouvement de stock
Les équipes d'entrepôt gérant les mouvements de stock ont souvent besoin de voir la catégorie de produit sans ouvrir chaque dossier de produit. Un champ lié sur stock.move.line pointant vers product_id.categ_id expose la catégorie directement sur la ligne de mouvement. Avec store=True, cela permet de regrouper les stocks entrants et sortants par catégorie de produit dans les vues de rapport d'inventaire, ce qui est particulièrement utile pour les entreprises gérant une large gamme de familles de produits.
Fabrication : Référence interne sur les composants de l'ordre de travail
Les responsables de production dans les entreprises de fabrication ont souvent besoin de voir la référence produit interne sur les lignes de composants de l'ordre de travail pendant la production. Un champ lié lisant product_id.default_code sur les lignes mrp.workorder place le numéro de référence exactement là où l'opérateur en a besoin, réduisant les erreurs causées par la sélection de produits similaires. Ce type de petite personnalisation a un impact réel sur la précision au sol de production.
Feuilles de temps et Projets : Département de l'employé
Lorsque les chefs de projet examinent les lignes de feuilles de temps, ils ont parfois besoin de voir à quel département appartient l'employé à des fins d'allocation des coûts. Un champ lié défini comme related='employee_id.department_id' sur account.analytic.line (le modèle de feuille de temps) affiche le département directement sur l'entrée de la feuille de temps. Stocké avec store=True, il permet de filtrer les feuilles de temps par département dans les rapports d'analyse de projet, rendant Odoo un outil de gestion de projet et d'allocation de ressources plus complet.
Créer ou personnaliser le champ lié
Il existe trois principales façons d'ajouter un champ Relatif à un modèle Odoo, en fonction de votre contexte technique et de la manière dont le déploiement est géré.
Utiliser Odoo Studio (Sans Code)
Odoo Studio vous permet d'ajouter des champs Relatifs sans écrire de Python. Voici comment procéder :
- Ouvrez Odoo Studio depuis le menu principal.
- Naviguez vers le formulaire où vous souhaitez ajouter le champ.
- Cliquez sur Ajouter un champ et choisissez Champ Relatif.
- Sélectionnez le chemin relationnel en cliquant à travers les champs disponibles étape par étape.
- Donnez au champ une étiquette et configurez s'il doit être stocké ou en lecture seule.
- Enregistrez et fermez Studio.
Studio crée automatiquement le champ avec un préfixe x_studio_ et le place dans la vue. C'est l'une des manières les plus efficaces d'utiliser les champs Odoo Studio pour ajouter des informations contextuelles aux formulaires existants. Aucun changement de base de données n'est nécessaire de votre part.
Utiliser Python dans un Module Personnalisé
Pour les développeurs travaillant sur la personnalisation d'Odoo par le code, les champs Relatifs sont définis dans la classe du modèle. C'est l'approche recommandée par le guide des développeurs Odoo pour tout changement nécessitant un contrôle de version et un déploiement multi-environnement :
from odoo import fields, models
class StockMoveLine(models.Model):
_inherit = 'stock.move.line'
product_category_id = fields.Many2one(
related='product_id.categ_id',
string='Catégorie de produit',
store=True,
)
Après avoir défini le champ, ajoutez-le à la vue XML pertinente afin qu'il apparaisse dans l'interface. Odoo gère automatiquement la création de la colonne de base de données lors de l'installation ou de la mise à niveau du module. C'est l'approche standard de développement Odoo pour une personnalisation Odoo fiable et maintenable.
Utilisation de l'API XML-RPC
Pour les déploiements gérés par programme, par exemple via un carnet de configuration à distance, les champs liés peuvent être créés via l'API XML-RPC en définissant l'attribut related sur la définition du champ :
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_partner_country_id',
'field_description': 'Pays du client',
'model_id': sale_order_model_id,
'ttype': 'many2one',
'relation': 'res.country',
'related': 'partner_id.country_id',
'store': True,
'readonly': True,
'state': 'manual',
}]
)
Lors de la création d'un champ lié via l'API, vous devez spécifier manuellement le bon ttype et relation, car l'API ne déduit pas automatiquement le type de la chaîne comme le fait l'ORM Python. C'est l'approche utilisée par Dasolo pour déployer des personnalisations de champs Odoo à distance via des scripts de configuration automatisés.
Meilleures pratiques
1. Stockez le champ lorsque le filtrage ou le regroupement est nécessaire
Si les utilisateurs ont besoin de filtrer une vue de liste par le champ lié, ou de regrouper des enregistrements par celui-ci dans un tableau croisé dynamique, ajoutez store=True. Sans cela, le filtrage au niveau de la base de données n'est pas possible, et Odoo devrait charger tous les enregistrements en Python pour appliquer le filtre, ce qui ne scale pas. Pour les champs uniquement affichés dans les vues de formulaire, un champ non stocké est parfaitement acceptable.
2. Gardez la chaîne aussi courte que possible
Une chaîne à deux niveaux comme partner_id.country_id est propre et performante. Une chaîne à quatre niveaux comme picking_id.sale_id.partner_id.country_id introduit plus de points de défaillance potentiels et est plus difficile à maintenir. Si vous vous retrouvez à construire des chaînes très profondes, envisagez si un champ calculé avec une logique Python explicite serait plus clair et plus facile à déboguer.
3. Comprenez ce que signifie réellement readonly=False
Un champ lié modifiable ne crée pas de copie locale des données. Il modifie l'enregistrement source. Si vous rendez partner_id.phone modifiable sur un bon de commande, le changement met à jour l'enregistrement du partenaire dans res.partner. Ce changement affecte tous les autres documents liés à ce partenaire. Assurez-vous que cela est intentionnel et informez toujours les utilisateurs lorsqu'un champ modifie un enregistrement partagé.
4. Utilisez les champs liés pour l'affichage, pas pour la duplication de données
Les champs liés sont destinés à faire ressortir des données existantes dans leur contexte, et non à les dupliquer. Si vous vous retrouvez à vouloir avoir une copie indépendante d'une valeur qui peut diverger de la source, un champ régulier avec une valeur par défaut définie par une action onchange ou automatisée est la bonne approche, pas un champ lié avec store=True et readonly=False.
5. Vérifiez les implications des droits d'accès
Un champ lié lit à travers un autre modèle. Si l'utilisateur actuel n'a pas accès en lecture à ce modèle, le champ peut retourner une valeur vide silencieusement. C'est un comportement de sécurité correct d'Odoo, mais cela peut confondre les utilisateurs qui voient un champ vide sans comprendre pourquoi. Lors de la conception de formulaires avec des champs liés, vérifiez que les rôles d'utilisateur attendus ont accès en lecture à tous les modèles de la chaîne.
Pièges courants
Filtrage sur un champ lié non stocké
C'est l'erreur la plus courante. Un développeur ou un consultant ajoute un champ lié à une vue en liste et essaie ensuite d'ajouter un filtre de recherche dessus. Si store=False (la valeur par défaut), Odoo ne peut pas filtrer par ce champ au niveau de la base de données. Le domaine générera soit une erreur, soit retournera silencieusement aucun résultat. Ajoutez toujours store=True à tout champ lié que vous prévoyez d'utiliser dans des filtres de recherche ou des clauses de regroupement.
Comportement inattendu de l'écriture à travers
Définir readonly=False sur un champ lié et être ensuite surpris que les modifications affectent l'enregistrement source est un problème très courant, surtout lorsque des champs liés sont ajoutés via Odoo Studio par des utilisateurs peu familiers avec les mécanismes. Avant de rendre un champ lié modifiable, confirmez toujours avec les parties prenantes de l'entreprise si elles souhaitent que les modifications se propagent vers le modèle source.
Ne pas gérer les champs intermédiaires vides
Si un champ de la chaîne est vide, le champ lié retourne False. Dans une vue de formulaire, cela signifie généralement que le champ apparaît vide. Dans un champ calculé ou une méthode Python qui lit la valeur du champ lié, vous devez gérer le cas False pour éviter les TypeErrors. Cela est facile à négliger lors des tests lorsque tous les enregistrements ont des données complètes, mais cela se manifeste en production lorsque des champs optionnels sont laissés vides.
Utiliser un champ lié là où un champ calculé est plus approprié
Les champs liés fonctionnent bien lorsque vous reflétez un seul champ à travers une chaîne relationnelle. Lorsque vous devez appliquer une logique, une transformation ou un comportement conditionnel sur la valeur, un champ calculé avec une méthode Python est le bon choix. Essayer de faire de la logique conditionnelle à travers une chaîne de champs liés conduit à des solutions de contournement difficiles à maintenir et faciles à casser lors des futures mises à jour d'Odoo. C'est un point commun dans tout tutoriel technique Odoo sur les types de champs.
Problèmes de performance avec de nombreux champs liés stockés sur de grands modèles
Chaque champ lié stocké nécessite une mise à jour lorsque la valeur source change. Si vous ajoutez dix champs liés stockés sur un modèle avec des centaines de milliers d'enregistrements, et que les champs sources se mettent à jour fréquemment, vous pouvez créer une charge d'écriture significative sur la base de données. Pour un développement Odoo à grande échelle, profilez l'impact sur la performance des champs liés stockés et privilégiez les champs d'affichage non stockés lorsque l'exactitude en temps réel n'est pas critique.
Conclusion
Le champ lié est l'un des outils les plus pratiques disponibles dans le cadre Odoo pour faire ressortir des informations contextuelles sans dupliquer les données. Il vous permet de lire à travers des chaînes relationnelles, d'afficher des valeurs provenant d'enregistrements liés directement dans n'importe quelle vue, et éventuellement de stocker ces valeurs pour le filtrage et le reporting.
Comprendre quand utiliser store=True, quand readonly=False est approprié, et comment gérer les champs intermédiaires vides vous fera gagner du temps et évitera les problèmes de données les plus courants dans les implémentations Odoo. Que vous soyez un développeur écrivant des modules Python, un consultant utilisant Odoo Studio, ou un responsable technique gérant des configurations à distance, le champ lié mérite d'être bien connu.
Si vous construisez ou étendez un modèle de données Odoo, les champs liés font partie de votre boîte à outils aux côtés des champs calculés, des champs Many2one, et des autres types de champs Odoo abordés dans cette série.
Chez Dasolo, nous aidons les entreprises à mettre en œuvre, personnaliser et optimiser Odoo dans les domaines des ventes, des opérations, de la comptabilité, et au-delà. Si vous avez besoin d'aide pour concevoir votre modèle de données Odoo, ajouter des champs personnalisés à vos flux de travail, ou étendre votre configuration Odoo avec un code fiable et maintenable, nous sommes là pour vous aider. Contactez-nous et discutons de la manière dont nous pouvons soutenir votre projet Odoo.