Introduktion
Når du begynder at arbejde med Odoo-udvikling, dukker begrebet arv konstant op. Odoos objekt-relationelle lag er bygget til, at modeller kan udvide og genbruge hinandens felter uden at kopiere data eller skrive gentaget kode.
Arvede felter er nøglen til denne arkitektur. De gør det muligt for en model at vise og bruge felter, som fysisk ligger på en anden model, så det føles som om feltet hører til begge steder. Når du forstår idéen, bliver mange andre dele af Odoo's datamodel lettere at overskue.
Denne guide beskriver, hvad arvede felter er, de tre inheritancetyper der skaber dem, hvordan de opfører sig i databasen, og hvordan du bruger dem i praktiske Odoo-tilpasninger.
Hvad er et arvet felt i Odoo?
I Odoo betragtes et felt som arvet, når en model får adgang til felter, der er defineret på en anden model via en af de tre arve-mekanismer. I stedet for at definere feltet på ny genbruger den underordnede model det, så der ikke skabes redundans.
Det er med til at holde Odoo’s datamodel kompakt og konsistent. Det samme navn på en kontakt vises konsekvent i salgsordrer, CRM-poster og fakturaer, fordi værdien læses fra ét fælles sted.
De tre arvetyper i Odoo
Odoo tilbyder tre forskellige måder at arve modeller på, og hver håndterer felter på sin egen måde.
1. Klassisk arv
Den mest udbredte metode: du bruger _inherit uden et nyt _name. Det udvider en eksisterende model ved at tilføje felter eller metoder direkte til den samme database-tabel. Der oprettes ingen ekstra tabel; de nye felter føjes til originalen.
Dette er måden, standardmoduler udvider core-modeller på. Når du f.eks. aktiverer CRM, tilføjes ekstra felter til res.partner via klassisk arv, og de bliver gemt i partner-tabellen ved siden af kernefelterne.
2. Prototype-arv
Her kombinerer du _inherit og _name. Den nye model starter som en kopi af forældermodelens struktur, men får sin egen database-tabel. Forælderens felter duplikeres til barnet, og ændringer i barnet påvirker ikke forælderen.
Mønstret er mindre hyppigt i standard-tilpasninger, men nyttigt når du vil skabe en helt ny model baseret på en eksisterende struktur.
3. Delegationsarv
Denne særlig karakteristiske variant bruger _inherits. Her linker barnet til forælderen via en Many2one, og barnet eksponerer forælderens felter, som om de var dets egne. Selve dataene opbevares i forældertabellen, ikke i barnet.
Det er oftest denne mekanisme, folk mener, når de taler om ’arvede felter’ i streng forstand: felterne kopieres ikke, men læses og skrives gennem relationslinket.
Et klassisk eksempel fra Odoo er res.users versus res.partner. Hver bruger er samtidig en kontakt; brugerens navn, e-mail og telefonnummer ligger på partneren og tilgås via delegationsarv.
Sådan fungerer feltet
Delegationsarv set teknisk
Når en model bruger _inherits, opretter Odoo en gennemsigtig bro mellem to databaserækker. Ved læsning følger ORM’en Many2one-linket til forælderens record og returnerer værdien derfra.
Ved skrivning skriver Odoo direkte i forældrekortet. For udvikleren føles feltet som en del af barnet; i databasen ligger værdien dog hos forælderen.
Det betyder også, at data ikke duplikeres. Ændrer du navnet på en partner, opdateres det samme navn straks alle steder, hvor partneren bruges — også i den bruger, der arver feltet.
Klassisk arv og databasen
Ved klassisk arv tilføjes nye felter direkte i den oprindelige models database-tabel. Der er ingen ekstra tabel; det er samme model og samme tabel i databasen. Det er ofte den reneste og mest direkte måde at udvide Odoo på.
Relaterede felter som letvægts-arv
Et related-felt er en særlig beregnet type, der læser en værdi gennem en kæde af relationer. Det er ikke identisk med model-arv, men bruges ofte til at vise data fra en anden model uden at ændre tabellens struktur.
Eksempelvis kan du lave et partner_country_id på en salgsordre, der peger på partner_id.country_id. For brugeren opfører feltet sig som om det hører til ordren, selvom værdien ligger på partneren.
Relaterede felter kan gemmes i databasen med store=True, hvilket gør søgninger og filtre hurtigere, men øger lagringsbehovet og kræver genberegning ved opdateringer.
Hvordan felter afgøres ved runtime
Når Odoo indlæser en model, løser det hele feltskemaet inklusive arvede og relaterede felter. Før modellen tages i brug er hver tilgængelige felt kortlagt til sin faktiske kilde — egen tabel, forældretabel via delegation eller en relation — og denne kortlægning caches for performance.
Forretningsscenarier
Arvede felter er ikke kun et teknisk trick; de løser konkrete forretningsbehov ved at sikre konsistens uden redundant lagring på tværs af systemet.
1. CRM og salg: kontaktinfo
Når en sælger opretter et lead, hentes kundeoplysninger som navn, telefon og e-mail fra partner-posten via Many2one. Ændres partnerens data, opdateres alle tilknyttede leads, tilbud og ordrer med det samme.
Det er et samspil mellem klassisk arv og relaterede felter: CRM-udvidelser tilfører partnermodellen CRM-specifikke felter, mens salgsordrer viser kontaktinfo via relaterede felter.
2. Produkter og varianter
Produktarkitekturen bruger delegationsarv til varianter. product.product linker til product.template via _inherits, så fælles felter som navn, kategori og salgpris ligger på templaten, mens variant-specifikke felter ligger på selve variant-arket.
Det betyder, at du kan have mange farvevarianter af en trøje, der alle deler samme navn og beskrivelse uden at gentage disse værdier i databasen for hver variant.
3. Brugere og kontakter
Hver bruger i Odoo er samtidig en kontakt. res.users bruger _inherits = {'res.partner': 'partner_id'}, så felter som navn, e-mail og adresse er tilgængelige begge steder og opdateres synkront.
4. Lager: bevægelser og produktdata
Bevægelseslinjer i lageret viser produktbeskrivelser, der trækkes fra produkttemplaten gennem relaterede felter. Lageransvarlige ser altid korrekte og opdaterede produktoplysninger i pluklisterne uden at lager-modulet duplikerer data.
5. Regnskab: fakturalinjer
Fakturalinjer refererer produkter og kunder. Produktnavne, kontoopsætninger og skatteindstillinger hentes via relationer fra produkt- og partnermodellerne, så bogholderiets visninger stemmer overens med salgskonfigurationen.
Oprette eller tilpasse arvede felter
Brug af Odoo Studio
Odoo Studio er no-code værktøjet til at tilføje felter og ændre visninger. Når du opretter et felt i Studio, udføres der underliggende klassisk arv: modellen udvides, og feltet tilføjes strukturen uden at du skriver Python.
Studio giver dig også mulighed for at oprette relaterede felter. Ved at vælge 'Related Field' peger du på en sti gennem relationer fra den aktuelle model — f.eks. at vise kundens land eller CVR direkte på salgsordren fra partneren.
For funktionskonsulenter og slutbrugere er Studio ofte den hurtigste og sikreste vej, da den håndterer feltnavne, database-migration og placering i views automatisk.
Tekniske tilpasninger med Python
Udviklere definerer arvede felter i Python ved hjælp af Odoo's models.Model-klasser, hvor typen af arv afgør hvordan felterne deklareres.
Klassisk arv er velegnet til at tilføje et felt på en eksisterende model:
class CrmLead(models.Model):
_inherit = 'crm.lead'
x_contract_value = fields.Float(
string='Estimated Contract Value'
)
Delegationsarv bruges til at skabe en ny model, der deler felter fra en eksisterende model:
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'
)
Relaterede felter bruges til at vise en værdi fra en linked record:
class SaleOrder(models.Model):
_inherit = 'sale.order'
partner_country_id = fields.Many2one(
related='partner_id.country_id',
string='Customer Country',
store=True
)
Via XML-RPC API (fjernkonfiguration)
Du kan også oprette felter programmatisk gennem Odoo's XML-RPC API ved at manipulere ir.model.fields. Dette svarer i praksis til det Studio gør, men kan køres som en del af automatiserede udrulningsscripts uden direkte serveradgang.
For at lave et relateret felt via API’et opretter du en ir.model.fields-post med passende ttype og angiver related-stien. Den metode er praktisk i automatiserede setups til kunder.
Gode fremgangsmåder
Vælg den rette arvstype til opgaven
Brug klassisk arv, når du bare vil tilføje felter eller metoder til en eksisterende model — det er enkelt og klart. Vælg delegationsarv når du har brug for to adskilte records, der meningsfuldt er forbundne (fx et forretningsobjekt, der bygger ovenpå en kontakt uden at være en kontakt i sig selv).
Foretræk relaterede felter ved læseadgang
Har du kun behov for at vise en værdi fra en relateret post, er et related-felt ofte renere end at indføre delegationsarv. Det undgår ekstra struktur-afhængigheder og er lettere at vedligeholde.
Vær forsigtig med store mængder store relaterede felter (store store=True)
At gemme relaterede felter øger søge- og filterhastighed, men gør dem til kopier. Odoo genberegner ved kildeændringer, men i kanttilfælde kan synkronisering glide. Gem kun relaterede felter, når du virkelig har brug for at filtrere eller gruppere store datasæt effektivt.
Prefix altid brugerdefinerede felter med x_
Navngivning med x_ (eller brug modul-namespace) hjælper med at undgå kollisioner med felter, som Odoo kan introducere i fremtidige versioner.
Dokumentér din arv-kæde
I komplekse tilpasninger er det værd at notere hvor et felt stammer fra og hvorfor strukturen er valgt. Et felt kaldet x_country_code på en salgsordre er ikke åbenlyst forbundet med partner_id.country_id.code uden en kort forklaring.
Håndtér kaskade-sletninger korrekt
Ved delegationsarv skabes forældrekortet ofte automatisk sammen med barnet. Når barnet slettes, bør forælderen normalt også slettes; sæt ondelete='cascade' på Many2one i _inherits for at undgå forældreløse rækker.
Almindelige faldgruber
Forveksling af de tre arvetyper
En hyppig fejl er at bruge _inherit sammen med _name uden at ville lave en helt ny model — det opretter ved et uheld en ny model i stedet for at udvide den eksisterende. Kontroller altid din modeldefinition: vil du ikke lave en ny tabel, så undlad _name.
Glemme at oprette forældrekortet ved _inherits
Ved delegationsarv oprettes forældrekortet ikke altid automatisk i alle situationer. Når du skaber records via API eller scripts, skal du enten lade ORM’en håndtere oprettelsen via normal create, eller oprette forælderen først og sende dens ID. Ellers får du constraint-fejl.
Forsøge at ændre felttype gennem arv
Odoo tillader ikke at ændre typen af et eksisterende felt via arv. Du kan justere label, hjælp-tekst eller domain, men ikke ændre en Char til en Integer — det vil føre til fejl ved installation af modulet.
Overforbrug af gemte relaterede felter
Fristelsen til at sætte store=True på alle relaterede felter kan øge ydeevnen kortsigtet, men det sprænger databasen og øger genberegningsarbejdet markant. Brug lagrede relaterede felter målrettet, når der er et konkret behov.
Antage at arvede felter automatisk følger adgangsregler på barnet
Felter via delegation ligger fysisk på forældermodellen. Rettigheder på barnet gælder ikke nødvendigvis i databasen for forælderen. Hvis du begrænser adgang til barnet, men ikke forælderen, kan brugere stadig nå felterne via forælderen. Gennemgå sikkerhedsregler for begge modeller ved delegation.
Konklusion
Arvede felter er ikke en nichefunktion — de er en integreret del af Odoo-arkitekturen. Forhold som brugere↔kontakter, varianter↔templates og ordre↔kundeinfo bygger på arv for at holde data korrekte og undgå duplikation.
At kunne vælge den rigtige arvstype, vide hvornår et related-felt er nok, og hvordan mekanismerne opfører sig i databasen gør dig langt mere effektiv til Odoo-tilpasning. Du skriver renere kode, bygger bedre datamodeller og bruger mindre tid på at fejlfinde uventet feltadfærd.
Kort sagt: Odoo's ORM er designet til, at data lever ét sted og tilgås mange steder. Det er princippet bag arvede felter, og det holder systemet sammen, selv når det vokser med mange sammenkoblede moduler.
Brug for hjælp til din Odoo-implementering?
Hos Dasolo hjælper vi virksomheder med at implementere, tilpasse og optimere Odoo. Uanset om du bygger et modul fra bunden, udvider standardmodeller med nye felter, eller prøver at forstå uventet dataadfærd, har vores team praktisk erfaring til at få dig videre hurtigere uden kostbare fejltrin.
Har du spørgsmål om din Odoo-datamodel, strategi for brugerdefinerede felter eller teknisk implementering, tager vi gerne en dialog om din situation. Kontakt os og lad os finde den rette fremgangsmåde for dit projekt.