Se rendre au contenu

Champs calculés stockés dans Odoo : Le guide complet

Comprendre comment fonctionnent les champs calculés stockés dans Odoo, quand les utiliser et comment les créer avec Python ou Odoo Studio.
6 mars 2026 par
Champs calculés stockés dans Odoo : Le guide complet
Dasolo
| Aucun commentaire pour l'instant

Introduction


Si vous avez passé du temps à travailler avec Odoo, vous avez probablement rencontré des champs qui calculent leur valeur automatiquement. Un champ calculé stocké va un pas plus loin : il calcule la valeur et l'enregistre directement dans la base de données.


Cette distinction est plus importante qu'elle ne le semble au premier abord. Un champ qui ne se calcule qu'à la volée ne peut pas être recherché, filtré, groupé ou exporté efficacement. Un champ calculé stocké peut l'être. Il se comporte comme une colonne de base de données ordinaire tout en étant piloté par la logique que vous définissez.


Ce guide couvre tout ce que vous devez savoir sur les champs calculés stockés dans Odoo : comment ils fonctionnent à l'intérieur du modèle de données Odoo, comment les créer en utilisant Odoo Studio ou Python, des cas d'utilisation réels en entreprise, et les erreurs les plus courantes à éviter.

Qu'est-ce qu'un champ calculé stocké dans Odoo


Dans l'ORM Odoo, chaque champ d'un modèle contient une pièce de données. La plupart des champs stockent ce que l'utilisateur saisit manuellement. Un champ calculé est différent : sa valeur est générée par une fonction Python plutôt que saisie par un utilisateur.


Un champ calculé stocké est simplement un champ calculé avec store=True. Lorsque ses dépendances changent, Odoo exécute la fonction de calcul et écrit le résultat dans la colonne de la base de données. La valeur est alors disponible comme n'importe quel autre champ.


En Python, le modèle de base ressemble à ceci :

total_amount = fields.Float(
    string='Montant Total',
    compute='_compute_total_amount',
    store=True,
)

@api.depends('quantity', 'unit_price')
def _compute_total_amount(self):
    for record in self:
        record.total_amount = record.quantity * record.unit_price

Le paramètre store=True est ce qui sépare un champ calculé stocké d'un champ calculé régulier. Sans cela, la valeur est recalculée chaque fois que le champ est lu mais n'est jamais persistée dans la base de données.


Dans l'interface Odoo, un champ calculé stocké ressemble exactement à n'importe quel autre champ. Les utilisateurs le voient sur les formulaires, les vues en liste et les rapports. Ils peuvent filtrer par celui-ci, regrouper des enregistrements en l'utilisant et l'inclure dans les exports. Il n'y a aucun indicateur visuel que la valeur est calculée plutôt qu'entrante.


Champs calculés stockés vs non stockés

Comprendre cette différence est essentiel pour tout travail de développement Odoo :

  • Champ calculé non stocké : Calculé à la volée lors de la lecture. Ne peut pas être utilisé dans des filtres, des recherches ou des regroupements. Moins lourd en stockage mais pas disponible pour les requêtes de base de données.
  • Champ calculé stocké : Calculé lorsque les dépendances changent et enregistré dans la base de données. Recherchable, filtrable, exportable. Prend de l'espace dans la base de données comme n'importe quelle colonne régulière.

Le choix entre les deux n'est pas une question de savoir lequel est mieux en général. Cela dépend de l'utilisation que vous avez du champ. Si vous ne l'affichez que sur un seul formulaire, le non stocké est suffisant. Si vous devez filtrer, trier ou agréger par celui-ci, utilisez le stocké.

Comment fonctionne le champ


Lorsque vous définissez un champ calculé stocké dans Odoo, le ORM met en place des déclencheurs de recomputation automatiques basés sur les champs listés dans le @api.depends() décorateur.


Chaque fois que l'un de ces champs dépendants change sur un enregistrement, Odoo marque cet enregistrement comme nécessitant une recomputation. La méthode de calcul s'exécute, et le résultat est réécrit dans la colonne de la base de données pour ce champ.


Le cycle de recomputation

Voici ce qui se passe étape par étape :

  1. Un utilisateur ou un processus automatisé modifie un champ qui est listé dans @api.depends().
  2. Odoo détecte le changement et identifie tous les enregistrements qui dépendent de ce champ.
  3. La méthode de calcul est appelée pour ces enregistrements.
  4. La valeur calculée est écrite dans la colonne de la base de données.
  5. Le champ est maintenant disponible pour la recherche, le filtrage et l'exportation avec la valeur mise à jour.

Dans la plupart des cas, cette recomputation se produit immédiatement dans la même transaction. Pour les opérations par lots importantes, Odoo peut différer certaines recomputations et les traiter en arrière-plan.


Dépendances entre modèles liés

Le décorateur @api.depends() prend en charge les chemins pointillés pour accéder aux champs sur les modèles liés. Par exemple :


@api.depends('partner_id.country_id.name')
def _compute_country_name(self):
    for record in self:
        record.country_name = record.partner_id.country_id.name or ''

Dans ce cas, Odoo suit les changements sur partner_id, country_id et name à travers les modèles. Si le nom du pays change chez un partenaire, tous les enregistrements liés sont automatiquement recomputés. C'est l'un des aspects les plus puissants du framework Odoo.


Impact de la base de données

Parce que le champ est stocké, Odoo crée une véritable colonne dans la table de base de données PostgreSQL. Cela signifie que le champ participe directement aux requêtes SQL. Les recherches et les filtres sur les champs calculés stockés sont rapides et efficaces, tout comme les recherches sur les champs réguliers.

Cas d'utilisation en entreprise


Les champs calculés stockés apparaissent dans tous les domaines d'Odoo. Voici cinq exemples pratiques tirés de véritables flux de travail d'entreprise.


1. Ventes : Pourcentage de marge sur les lignes de commande

Une équipe de vente souhaite voir le pourcentage de marge sur chaque ligne de commande sans ouvrir de calculatrice. Un champ calculé stocké prend le prix unitaire et le prix de revient, calcule la marge et la stocke sur la ligne. Le responsable des ventes peut alors filtrer les commandes par pourcentage de marge, trouver instantanément les lignes non rentables et regrouper par bandes de marge dans les vues en tableau croisé dynamique.


2. CRM : Jours sans activité sur un prospect

Un champ calculé stocké sur le modèle de prospect CRM peut suivre combien de jours se sont écoulés depuis la dernière activité prévue. Associez cela à une action planifiée qui déclenche la recomputation chaque matin, et votre équipe de vente peut filtrer les prospects par seuil d'inactivité. Aucun suivi manuel requis.


3. Inventaire : Quantité nette disponible

Pour les produits avec des règles de stock complexes, un champ calculé stocké peut contenir une valeur pré-calculée telle que la quantité en main moins la quantité réservée. Comme la valeur est stockée, les responsables produits peuvent trier et filtrer la liste des produits par disponibilité sans qu'Odoo n'exécute des calculs de stock complexes en direct pour chaque ligne à l'écran.


4. Comptabilité : Nombre de factures en retard par client

Sur le modèle client, un champ calculé stocké peut compter combien de factures sont actuellement en retard. Lorsque l'équipe comptable ouvre la liste des contacts, elle peut trier les clients par nombre de factures en retard en un clic. Cela n'est possible que parce que le compte est stocké dans la base de données plutôt que calculé à la volée pour chaque ligne.


5. Fabrication : Durée totale de travail estimée

Dans une nomenclature, un champ calculé stocké peut additionner la durée estimée de toutes les opérations des centres de travail attachées à la nomenclature. Les planificateurs de production peuvent ensuite filtrer et trier les nomenclatures par temps de travail total, ce qui est utile pour la planification de la capacité et la programmation. Chaque fois qu'une opération est ajoutée ou modifiée, le total se met à jour automatiquement.

Créer ou personnaliser le champ


Il existe deux principales façons de créer des champs calculés stockés dans Odoo : en utilisant Odoo Studio pour des cas simples, ou en écrivant du code Python dans un module personnalisé pour un contrôle total.


Utilisation d'Odoo Studio

Odoo Studio vous permet d'ajouter des champs calculés sans écrire de code. Lorsque vous créez un nouveau champ de type Integer, Float ou Monetary dans Studio, vous pouvez activer une option de formule qui accepte une expression de type Python. Studio gère le suivi des dépendances en arrière-plan.


Les champs calculés dans Studio sont adaptés lorsque la logique est une simple expression arithmétique entre des champs sur le même enregistrement. Ils sont faciles à configurer et ne nécessitent pas d'environnement de développement. Cependant, ils ont de réelles limites. Si votre logique implique des champs de modèles liés, des branches conditionnelles ou une agrégation à travers des enregistrements enfants, Studio ne sera pas suffisant. Vous aurez besoin d'un module personnalisé.


C'est une distinction importante lors de la planification de votre personnalisation Odoo : Studio est rapide pour les cas simples, mais Python vous offre une flexibilité totale lorsque la logique devient complexe.


Utilisation d'un module Python personnalisé

Pour tout ce qui dépasse les formules de base, vous définissez le champ en Python à l'intérieur d'un module Odoo personnalisé. Voici un exemple concret qui ajoute un champ de pourcentage de marge aux lignes de commande de vente :


from odoo import models, fields, api

class SaleOrderLine(models.Model):
    _inherit = 'sale.order.line'

    x_margin_pct = fields.Float(
        string='Marge %',
        compute='_compute_margin_pct',
        store=True,
        digits=(5, 2),
    )

    @api.depends('price_unit', 'purchase_price')
    def _compute_margin_pct(self):
        for line in self:
            if line.price_unit:
                line.x_margin_pct = (
                    (line.price_unit - line.purchase_price) / line.price_unit
                ) * 100
            else:
                line.x_margin_pct = 0.0

Lorsque ce module est installé, Odoo crée la colonne x_margin_pct dans la base de données, exécute la méthode de calcul pour tous les enregistrements existants et commence à suivre les changements de price_unit et purchase_price à partir de ce moment.


Le préfixe de champ x_ est la convention pour les champs personnalisés dans Odoo afin d'éviter les conflits avec les champs de base. C'est une pratique standard dans le développement Odoo.


Rendre un champ calculé stocké modifiable

Par défaut, les champs calculés sont en lecture seule. Si vous souhaitez que les utilisateurs puissent remplacer manuellement la valeur calculée, vous pouvez définir une méthode inverse en parallèle de votre méthode de calcul. La méthode inverse s'exécute lorsqu'un utilisateur écrit directement dans le champ et peut mettre à jour les champs sources en conséquence. Ce modèle est utile pour les champs où la valeur calculée est un bon défaut mais nécessite parfois un remplacement manuel.


Champs Odoo Studio et l'API XML-RPC

Pour les équipes gérant les champs de base de données Odoo via l'API XML-RPC, vous pouvez créer des champs standards via le modèle ir.model.fields. Cependant, pour les champs calculés stockés avec une logique Python personnalisée, la méthode de calcul elle-même doit se trouver dans le code côté serveur. L'approche API fonctionne bien pour la provision de champs simples dans le cadre de déploiements automatisés, mais la logique derrière un champ calculé nécessite toujours un module personnalisé installé sur le serveur.

Meilleures pratiques


Voici les pratiques que suivent les consultants Odoo expérimentés lorsqu'ils travaillent avec des champs calculés stockés.


Déclarez toutes les dépendances avec précision

Le décorateur @api.depends() doit lister chaque champ que votre méthode de calcul lit. Si vous en oubliez un, le champ ne sera pas mis à jour lorsque cette dépendance changera. Passez en revue votre méthode de calcul ligne par ligne et assurez-vous que chaque accès au champ est listé dans le décorateur.


Gardez les méthodes de calcul rapides

Votre méthode de calcul s'exécute sur chaque enregistrement affecté par un changement de dépendance. Dans une instance Odoo occupée, cela peut signifier des milliers d'enregistrements à la fois. Évitez les requêtes de base de données à l'intérieur des méthodes de calcul lorsque cela est possible. Si vous devez accéder à des données connexes, utilisez les champs qui sont déjà chargés plutôt que d'effectuer des recherches supplémentaires.


N'utilisez store=True que lorsque vous en avez besoin

Les champs stockés consomment de l'espace de base de données et déclenchent des opérations d'écriture à chaque recomputation. Si vous n'avez besoin d'afficher le champ que dans une vue de formulaire et que vous ne le filtrez ni ne le regroupez jamais, un champ calculé non stocké est l'option la plus légère. Prenez cette décision délibérément plutôt que de par défaut à stocké pour tout.


Gérez les cas particuliers dans la méthode de calcul

Tenez toujours compte des valeurs vides ou manquantes dans votre méthode de calcul. La division par zéro, les enregistrements connexes manquants et les valeurs nulles sont des causes courantes d'erreurs silencieuses dans les champs calculés. Ajoutez des vérifications explicites et définissez des valeurs par défaut sûres lorsque le calcul normal ne peut pas se poursuivre.


Planifiez la recomputation initiale sur de grandes tables

Lorsque vous installez un module qui ajoute un nouveau champ calculé stocké, Odoo le recompute pour chaque enregistrement existant dans la table. Sur une table avec des centaines de milliers de lignes, cela peut prendre un temps significatif. Testez votre migration dans un environnement de staging d'abord et prévoyez un temps d'arrêt potentiel ou un traitement en arrière-plan lors du déploiement en production.


Évitez les dépendances circulaires

Si le champ A dépend du champ B et que le champ B dépend du champ A, Odoo générera une erreur lors du chargement du module. Concevez vos dépendances de champ calculé pour qu'elles s'écoulent dans une seule direction.

Pièges courants


Oublier store=True

C'est l'erreur la plus courante. Le champ s'affiche correctement dans la vue de formulaire, donc tout semble bien pendant les tests. Ensuite, quelqu'un essaie de l'ajouter comme filtre ou de l'inclure dans un rapport, et cela ne fonctionne pas. Avant d'écrire toute logique de calcul, décidez à l'avance si vous avez besoin que le champ soit consultable. Si oui, ajoutez store=True dès le départ.


Dépendance manquante dans @api.depends

Si votre méthode de calcul lit partner_id.country_id mais que votre décorateur ne liste que partner_id, le champ ne se mettra pas à jour lorsque le pays changera sur l'enregistrement du partenaire. Suivez le chemin complet de chaque accès au champ dans votre méthode et listez chaque étape explicitement dans le décorateur.


Erreurs silencieuses dans la méthode de calcul

Si votre méthode de calcul génère une exception pour un enregistrement, Odoo ignore silencieusement la recomputation pour cet enregistrement et conserve la valeur stockée précédente. L'erreur peut apparaître dans les journaux du serveur mais rien n'est montré à l'utilisateur. Cela peut conduire à des valeurs obsolètes ou incorrectes qui sont difficiles à tracer. Testez toujours votre méthode de calcul sur des enregistrements ayant des données manquantes ou inhabituelles.


Dégradation des performances sur de grands ensembles de données

Une méthode de calcul qui fonctionne bien pendant le développement peut devenir un goulot d'étranglement sérieux en production si la table croît jusqu'à des dizaines de milliers d'enregistrements. Faites attention au nombre de requêtes de base de données que votre méthode de calcul déclenche par enregistrement. Une seule requête supplémentaire par enregistrement multipliée par dix mille enregistrements représente dix mille requêtes pour une seule opération de sauvegarde.


Utiliser sudo() dans les méthodes de calcul

Appeler sudo() à l'intérieur d'une méthode de calcul pour contourner les droits d'accès est un risque de sécurité. Si la valeur calculée expose des données que l'utilisateur actuel ne devrait pas voir, le renvoi de celle-ci par le biais d'une méthode de calcul contredit le modèle de permission d'Odoo. Utilisez sudo() dans les méthodes de calcul uniquement lorsque vous avez délibérément réfléchi aux implications de sécurité.


S'attendre à une recomputation immédiate dans tous les contextes

Dans la plupart des opérations interactives, la recomputation est synchrone. Mais lors d'importations par lots, de travaux en arrière-plan ou de certaines opérations ORM avec des indicateurs de contexte, Odoo peut différer la recomputation. Ne construisez pas de logique métier qui suppose que la valeur stockée est toujours à jour au moment exact où un enregistrement est écrit. Vérifiez le comportement dans le contexte spécifique où votre champ sera utilisé.

Conclusion


Les champs calculés stockés sont l'un des outils les plus utiles disponibles lors de la création ou de l'extension d'Odoo. Ils vous permettent d'automatiser les calculs, de garder vos données cohérentes et de rendre les enregistrements recherchables et exportables sans aucun travail manuel de la part de vos utilisateurs.


Les points clés à retenir :

  • Utilisez store=True lorsque vous avez besoin que le champ soit recherchable, filtrable ou exportable.
  • Déclarez toujours toutes les dépendances dans @api.depends(), y compris les chemins inter-modèles.
  • Gardez les méthodes de calcul rapides et gérez explicitement les cas particuliers.
  • Pour des formules simples, Odoo Studio est une option rapide. Pour tout ce qui est plus complexe, écrivez en Python.
  • Prévoyez une recomputation initiale lors du déploiement en production sur de grandes tables.

Que vous construisiez un nouveau module personnalisé, que vous étendiez un modèle Odoo existant ou que vous exploriez les types de champs Odoo pour la première fois, les champs calculés stockés valent la peine d'être compris en profondeur. Ils se situent à l'intersection de l'ORM Odoo, de la couche de base de données et de votre logique métier.


Besoin d'aide avec votre mise en œuvre d'Odoo ?

Dasolo aide les entreprises à mettre en œuvre, personnaliser et optimiser Odoo pour une large gamme de besoins commerciaux. Que vous ayez besoin d'ajouter des champs calculés à votre modèle de données, de créer des rapports basés sur des valeurs calculées, ou d'aller plus loin dans votre développement Odoo, notre équipe a l'expérience nécessaire pour vous aider.


Contactez-nous si vous avez besoin de soutien pour votre projet Odoo. Nous serons ravis de discuter de votre cas d'utilisation et de trouver la bonne approche pour votre entreprise.

Champs calculés stockés dans Odoo : Le guide complet
Dasolo 6 mars 2026
Partager cet article
Se connecter pour laisser un commentaire.