Passa al contenuto

Campi Ereditati in Odoo: Come l'ORM Condivide i Dati Tra Modelli

Guida pratica per comprendere l’ereditarietà dei campi in Odoo e come applicarla nelle tue personalizzazioni
6 marzo 2026 di
Campi Ereditati in Odoo: Come l'ORM Condivide i Dati Tra Modelli
Dasolo
| Ancora nessun commento

Introduzione


Quando inizi a sviluppare su Odoo, un concetto ricorre continuamente: l'ereditarietà dei modelli. L'ORM di Odoo è pensato per far sì che modelli diversi possano riutilizzare campi e comportamento senza replicare dati o codice inutilmente.


I campi ereditati sono il fulcro di questo design. Permettono a un modello di esporre e usare campi fisicamente memorizzati in un altro modello in modo trasparente. Capire questo meccanismo chiarisce molte scelte progettuali del data model di Odoo.


Questa guida illustra il concetto di campo ereditato, i tre tipi di ereditarietà dei modelli che li generano, il loro comportamento a livello di database e come sfruttarli nelle personalizzazioni reali.

Che cos'è un campo ereditato in Odoo?


Nel framework ORM di Odoo, un campo è considerato ereditato quando un modello accede a campi definiti su un modello diverso tramite uno dei tre meccanismi di ereditarietà supportati. Invece di ridefinire il campo, il modello figlio lo riutilizza.


È così che Odoo mantiene il modello dati snello e coerente: lo stesso campo name presente su un contatto è lo stesso nome mostrato nelle offerte, nei lead e nelle fatture perché tutti leggono dalla stessa fonte.


I tre tipi di ereditarietà in Odoo

Odoo prevede tre modalità distinte per ereditare modelli, e ognuna tratta i campi in modo diverso.

1. Ereditarietà classica

Questo è il pattern più usato: si dichiara _inherit senza creare un nuovo _name. Si estende il modello esistente aggiungendo campi o metodi; non si crea una nuova tabella DB. I campi aggiunti compaiono direttamente sul modello originale.


È il modo in cui i moduli standard inseriscono nuovi campi su modelli come res.partner: i campi vengono memorizzati nella stessa tabella del modello base.


2. Ereditarietà per prototipo

Qui si usano insieme _inherit e _name. Il nuovo modello copia la struttura del genitore ma ha una propria tabella nel database: i campi del padre vengono duplicati nel figlio e le modifiche al figlio non impattano il padre.


Questo approccio è meno frequente nelle personalizzazioni quotidiane, ma serve quando vuoi creare un modello nuovo con la stessa struttura di uno esistente.


3. Ereditarietà per delega

La più particolare: definita con _inherits. Il modello figlio contiene un Many2one verso il padre e rende disponibili tutti i campi del genitore come se fossero suoi. I dati risiedono nella tabella del genitore, non in quella del figlio.

È il caso tipico di cui parlano gli sviluppatori quando discutono dei campi ereditati in senso stretto: i campi non vengono replicati ma vengono letti e scritti tramite il link relazionale.


Un esempio onnipresente è la relazione fra res.users e res.partner: ogni utente è anche un partner e campi come nome ed email sono conservati sul partner e visibili dall'utente grazie alla delega.

Come funziona il campo


Ereditarietà per delega: cosa succede realmente

Con _inherits, l'ORM crea un ponte trasparente tra due tabelle. Leggere un campo ereditato dal figlio significa seguire il Many2one fino al record genitore e restituire il valore salvato lì.


Analogamente, scrivendo su quel campo dal modello figlio, Odoo aggiorna direttamente il record del genitore. Al livello di codice il campo appare nativo; a livello di storage il valore risiede nel padre.


La conseguenza pratica è che non esiste duplicazione dei dati: aggiornando il nome del partner la modifica è subito visibile ovunque il partner sia usato, inclusi gli utenti che lo ereditano.


Ereditarietà classica e il database

Nell'ereditarietà classica i campi aggiunti finiscono nella tabella originale del modello. Non ci sono tabelle secondarie: il modello esteso e quello base coincidono nel database. È il metodo più pulito e comune per estendere Odoo.


Campi related come ereditarietà leggera

Un campo related è un campo computato che legge il valore da un record collegato percorrendo una catena relazionale. Non è propriamente ereditarietà di modello, ma serve spesso per esporre dati provenienti da altri modelli senza toccare la struttura.


Per esempio, potresti avere su un ordine di vendita un campo partner_country_id che legge partner_id.country_id. In apparenza è un campo dell'ordine, ma il valore arriva dal partner.

I campi related possono essere salvati in DB con store=True, migliorando ricerca e filtro, ma aumentando lo spazio occupato e richiedendo ricalcolo quando la fonte cambia.


Come vengono risolti i campi in fase di esecuzione

All'avvio del server Odoo risolve la mappa completa dei campi del modello, includendo quelli ereditati. A quel punto ogni campo è già collegato alla sua origine — sia che provenga dalla stessa tabella, dal genitore tramite delega o da una catena related — e questa risoluzione viene memorizzata per performance.

Casi d'uso aziendali


I campi ereditati non sono solo una questione tecnica: risolvono problemi concreti mantenendo coerenza dei dati in tutta l'istanza senza duplicazioni inutili.


1. CRM e vendite: informazioni di contatto

Quando un commerciale crea un lead, il nome, telefono e email del cliente vengono dal record partner tramite un Many2one. Aggiornando i dati del partner, lead, preventivi e ordini collegati ricevono subito l'aggiornamento.


Qui operano insieme ereditarietà classica e campi related: il modulo CRM estende res.partner con campi specifici e gli ordini mostrano i contatti del partner tramite campi related.


2. Prodotti e varianti

Il modello prodotti usa la delega per gestire varianti: product.product si _inherits da product.template. Campi comuni (nome, prezzo, descrizione) vivono sul template; quelli specifici della variante (barcode, riferimento interno) restano sulla variante.


Questo permette, per esempio, di avere 50 varianti di colore di una maglia che condividono nome e descrizione senza memorizzarle 50 volte.


3. Utenti e contatti

Ogni utente è anche un contatto: res.users eredita da res.partner con _inherits, quindi nome, email, telefono e indirizzo sono gestiti sul partner e visibili sull'utente; una modifica si riflette su entrambi.


4. Magazzino: movimenti e informazioni prodotto

Le righe di movimento mostrano descrizioni prodotto che provengono dal template attraverso campi related. I responsabili di magazzino vedono informazioni aggiornate senza duplicazione nelle strutture dell'inventario.


5. Contabilità: righe di fattura

Le righe contabili fanno riferimento a prodotti e contatti: nome prodotto, conti e tasse vengono riportati dai modelli prodotto e partner tramite link relazionali, garantendo che i dati contabili coincidano con quelli impostati in vendite.

Creare o personalizzare campi ereditati


Usare Odoo Studio

Odoo Studio è l'interfaccia no-code per personalizzare modelli e viste. Aggiungendo un campo da Studio in realtà si usa l'ereditarietà classica: il modello viene esteso e il campo viene inserito nella sua definizione.


Studio consente anche di creare campi related. Se scegli "Related Field" puoi puntare a qualsiasi campo accessibile tramite una catena relazionale dal modello corrente, per esempio leggere il paese o la partita IVA del cliente su un ordine di vendita.


Per consulenti funzionali e utenti di business, Studio è spesso la soluzione più pratica: gestisce nomi, migrazioni DB e posizionamento nelle viste automaticamente.


Personalizzazioni tecniche con Python

Gli sviluppatori definiscono i campi ereditati in Python usando la classe models.Model dell'ORM di Odoo.


Ereditarietà classica per aggiungere un campo a un modello esistente:

class CrmLead(models.Model):
    _inherit = 'crm.lead'

    x_contract_value = fields.Float(
        string='Estimated Contract Value'
    )

Ereditarietà per delega per creare un nuovo modello che condivide i campi di un altro:

class EmployeeProfile(models.Model):
    _name = 'hr.employee.profile'
    _inherits = {'res.partner': 'partner_id'}

    partner_id = fields.Many2one(
        'res.partner',
        required=True,
        ondelete='cascade'
    )
    employee_id = fields.Many2one(
        'hr.employee',
        string='Employee'
    )

Campi related per esporre valori da record collegati:

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

    partner_country_id = fields.Many2one(
        related='partner_id.country_id',
        string='Customer Country',
        store=True
    )

Tramite API XML-RPC (configurazione remota)

È possibile creare campi anche via API XML-RPC usando il modello ir.model.fields. È lo stesso risultato di Studio e consente di aggiungere campi senza accesso diretto al server, utile per automazioni e deployment remoti.


Per aggiungere un campo related via API si crea un record ir.model.fields impostando il tipo (ttype) e il parametro related con il percorso relazionale; ideale per configurazioni ripetibili.

Buone pratiche


Scegli il tipo di ereditarietà giusto

Usa l'ereditarietà classica quando vuoi semplicemente estendere un modello con nuovi campi o metodi: è semplice e la scelta più comune. Riserva la delega a situazioni in cui servono due insiemi di record collegati ma distinti concettualmente.


Preferisci i campi related per sola lettura

Se ti serve solo mostrare un valore da un record collegato su una vista, un campo related è più chiaro della delega: non introduce una dipendenza strutturale e resta facile da mantenere.


Usa con attenzione store=True sui campi related

Memorizzare un campo related accelera filtri e ricerche ma crea una copia che va ricalcolata quando la fonte cambia; in casi limite può risultare fuori sincronizzazione. Salva in DB solo se serve davvero per filtrare o raggruppare su grandi volumi.


Prefissa sempre i campi custom con x_

Qualsiasi campo aggiunto a un modello standard dovrebbe iniziare con x_ (o usare il namespace del modulo) per evitare collisioni con campi che Odoo potrebbe aggiungere in futuro.


Documenta la catena di ereditarietà

In personalizzazioni complesse annota dove provengono i campi e perché. Un campo chiamato x_country_code su un ordine potrebbe non rimandare chiaramente a partner_id.country_id.code senza una breve documentazione.


Gestisci correttamente le cancellazioni a catena

Nella delega il record genitore viene creato automaticamente al salvataggio del figlio. Alla cancellazione, il genitore dovrebbe essere rimosso per evitare record orfani: imposta ondelete='cascade' sul Many2one in _inherits.


Errori comuni


Confondere i tre tipi di ereditarietà

L'errore più comune è usare _inherit insieme a _name quando si intendeva solo estendere il modello: così si crea un modello nuovo invece di estendere quello esistente. Se non vuoi un nuovo modello, non dichiarare _name.


Dimenticare di creare il record genitore in _inherits

Con la delega il record genitore non si crea automaticamente in ogni scenario: se crei il figlio tramite API o script potresti dover creare il genitore prima o lasciare che l'ORM lo faccia con create. Saltare questo passaggio causa errori di vincolo.


Cercare di cambiare il tipo di un campo via ereditarietà

Non si può sovrascrivere il tipo di un campo esistente tramite ereditarietà: puoi cambiare etichette, dominio o help, ma non trasformare un Char in un Integer. Tentare di farlo genera un errore in fase d'installazione del modulo.


Abusare dei related memorizzati

Mettere store=True a tutti i related per migliorare le performance può aumentare molto lo spazio e la manutenzione. Se il campo sorgente cambia spesso, il ricalcolo sarà costante. Usa store solo quando necessario per reporting o filtri su grandi dataset.


Assumere che i permessi del modello figlio si applichino automaticamente ai campi ereditati

I campi ereditati tramite delega risiedono sul modello genitore: i diritti sul figlio non si trasferiscono automaticamente al livello DB. Se limiti l'accesso al figlio ma non al padre, gli utenti potrebbero comunque leggere i valori tramite il genitore. Controlla le regole di sicurezza per entrambi i modelli.

Conclusione


I campi ereditati non sono una funzionalità marginale: sono parte integrante dell'architettura di Odoo. Relazioni come utente–partner, variante–template o ordine–informazioni cliente si basano su di essi per mantenere coerenza senza duplicare dati.


Sapere quale tipo di ereditarietà usare, quando preferire un campo related e come questi meccanismi si comportano in DB ti renderà più efficace nelle personalizzazioni: codice più pulito, modelli migliori e meno tempo speso a risolvere problemi imprevisti.


In sintesi: l'ORM di Odoo è progettato perché i campi risiedano in un unico punto e vengano letti da più posti. Questo principio sta alla base dei campi ereditati e mantiene il modello dati coerente anche quando il sistema cresce con tanti moduli interconnessi.

Serve supporto per la tua implementazione Odoo?


Da Dasolo supportiamo aziende nell'implementazione, personalizzazione e ottimizzazione di Odoo. Che tu debba sviluppare un modulo su misura, estendere modelli standard o capire comportamenti strani del data model, il nostro team ha esperienza pratica per aiutarti a muoverti più velocemente ed evitare errori costosi.


Se vuoi confrontarti sul tuo data model Odoo, sulla strategia dei campi custom o sull'implementazione tecnica, siamo disponibili a esaminare il tuo caso. Contattaci e troviamo insieme l'approccio più adatto al tuo progetto.

Campi Ereditati in Odoo: Come l'ORM Condivide i Dati Tra Modelli
Dasolo 6 marzo 2026
Condividi articolo
Accedi per lasciare un commento