Innledning
Hvis du har jobbet med Odoo en stund, kjenner du sikkert felt som fylles ut automatisk. Et lagret beregnet felt går et skritt lenger: verdien kalkuleres av systemet og skrives direkte til databasen som en vanlig kolonne.
Denne forskjellen har praktiske konsekvenser. Felt som kun beregnes ved visning kan verken søkes, filtreres eller grupperes effektivt i databasen. Når verdien er lagret, kan du bruke den i søk, eksport og pivot-rapporter like enkelt som et manuelt felt.
Denne veiledningen forklarer alt du trenger om lagrede beregnede felt i Odoo: hvordan de er bygget inn i datamodellen, hvordan du lager dem i Studio eller med Python, nyttige forretningsbruk og hvilke feil du bør unngå.
Hva er et lagret beregnet felt i Odoo
I Odoo sin ORM representerer hvert felt en bit data på en modell. De fleste felt fylles inn av brukeren, men et beregnet felt får sin verdi fra kode — vanligvis en Python-funksjon — i stedet for fra et direkte brukerinnputt.
Et lagret beregnet felt er i praksis et beregnet felt med store=True. Når avhengigheter endres, kjører Odoo beregningsmetoden og skriver resultatet ned i databasen, slik at feltet oppfører seg som et vanlig kolonnefelt.
I Python følger man gjerne et fast mønster for å definere slike felt:
total_amount = fields.Float(
string='Total Amount',
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
store=True er det som avgjør om feltet blir vedvart i databasen. Uten dette flagget regnes verdien kun ut ved lesing og lagres ikke i databasen.
I Odoo-grensesnittet oppleves et lagret beregnet felt som hvilket som helst annet felt: det vises i skjemaer, listinger og rapporter, og brukere kan filtrere, gruppere og eksportere på det uten å se at det er beregnet.
Lagret vs. ikke-lagret beregnet felt
Dette skillet er viktig for alle som jobber med Odoo-utvikling:
- Ikke-lagret beregnet felt: Beregnes ved lesing. Kan ikke brukes i søk, filter eller gruppering. Bruker lite lagringsplass, men er ikke tilgjengelig for database-spørringer.
- Lagret beregnet felt: Beregnes når avhengigheter endres og skrives til databasen. Kan søkes, filtreres og eksporteres. Opptar plass i databasen som et vanlig felt.
Valget handler ikke om hva som er universelt best, men om hva du trenger. Skal feltet bare vises i et skjema, er ikke-lagret ofte tilstrekkelig. Skal du sortere, filtrere eller aggregere etter feltet, må det være lagret.
Hvordan feltet fungerer
Når du definerer et lagret beregnet felt, setter Odoo ORM opp automatiske triggere for når beregningen skal kjøre, basert på feltene du lister i @api.depends()-dekoratøren.
Når noen av de avhengige feltene endres, merker Odoo posten for ny beregning, kjører compute-metoden og skriver verdien tilbake til tabellkolonnen.
Reberegningslivssyklus
Slik skjer handlingene i praksis steg for steg:
- En bruker eller et automatisert skript oppdaterer et felt som er oppført i
@api.depends(). - Odoo oppdager endringen og identifiserer hvilke poster som berøres.
- Compute-metoden kalles for disse postene.
- Den nye verdien skrives til databasen for feltet.
- Feltet er nå søkbart, filtrerbart og eksportklart med oppdatert verdi.
Vanligvis skjer dette umiddelbart i samme transaksjon. Ved store batch-operasjoner kan Odoo utsette enkelte rekalkuleringer og behandle dem i bakgrunnen.
Avhengigheter på tvers av relaterte modeller
@api.depends() støtter punktert sti-notasjon for felter på relaterte modeller, for eksempel:
@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 ''
Her sporer Odoo endringer på partner, land og navn på tvers av modeller. Hvis landet endres, trigges recompute automatisk for alle tilknyttede poster — en kraftig funksjon i Odoo-rammeverket.
Innvirkning på databasen
Siden feltet blir lagret, opprettes en faktisk kolonne i PostgreSQL-tabellen. Det betyr at feltet kan brukes direkte i SQL-spørringer, og søk/filtre blir raske og effektive, likt øvrige felt.
Forretningsscenarier
Lagrede beregnede felt er nyttige i mange forretningsprosesser. Her er fem konkrete eksempler fra praksis.
1. Salg: Marginprosent på ordrelinjer
Selgere vil raskt se marginen per ordrelinje uten å regne. Et lagret felt kan beregne og lagre margin basert på salgspris og kostpris, slik at ledere kan filtrere og gruppere på marginbånd i pivot-rapporter.
2. CRM: Dager uten aktivitet på leads
Et felt på lead-modellen kan lagre antall dager siden siste aktivitet. Kombinert med en daglig planlagt handling som trigget recompute får salgsavdelingen en enkel måte å filtrere ut inaktive leads.
3. Lager: Netto tilgjengelig mengde
For produkter med komplisert lagerlogikk kan et lagret felt holde forhåndsberegnet tilgjengelig lager (på lager minus reservert). Når verdien er lagret, kan produktansvarlige sortere og filtrere uten å kjøre tunge beregninger live.
4. Regnskap: Antall forfalte fakturaer per kunde
På kontaktkortet kan et lagret felt telle hvor mange fakturaer som er forfalte. Regnskapsavdelingen kan dermed sortere kunder etter antall forfalte forenklet, fordi tallet ligger klart i databasen.
5. Produksjon: Total estimert arbeidstid
I en stykkliste kan et lagret felt summere estimert tid fra alle arbeidsoperasjoner. Planleggere kan filtrere og prioritere stykklister etter samlet arbeidstid for bedre kapasitetsplanlegging.
Opprette eller tilpasse feltet
Du kan opprette lagrede beregnede felt enten raskt i Odoo Studio for enkle uttrykk eller i en egen Python-modul når logikken trenger full kontroll.
Bruke Odoo Studio
Studio lar deg legge til beregnede felt uten koding. For numeriske felt kan du aktivere en formel-funksjon som tar et Python-lignende uttrykk, og Studio håndterer avhengighetssporingen automatisk.
Studio passer fint for enkle aritmetiske uttrykk innen samme post. Når logikken krever tilgang til relaterte modeller, betingelser eller aggregater over underposter, er Studio for begrenset — da er en modul med Python nødvendig.
Dette er et viktig planleggingspunkt i Odoo-tilpasninger: Studio gir fart ved enkle behov, mens Python gir fleksibilitet ved kompleks logikk.
Bruke en egendefinert Python-modul
For mer avanserte scenarier definerer du feltet i Python i en modul. Et vanlig eksempel er å legge til marginprosent på salgslinjer:
from odoo import models, fields, api
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
x_margin_pct = fields.Float(
string='Margin %',
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
Når modulen installeres, opprettes kolonnen i databasen, beregningen kjøres for eksisterende poster, og Odoo begynner å følge opp endringer på oppgitte avhengigheter.
Prefikset x_ er en vanlig konvensjon for egendefinerte felt i Odoo for å unngå kollisjoner med kjernen — en standard praksis i Odoo-utvikling.
Gjør et lagret beregnet felt redigerbart
Som standard er beregnede felt skrivebeskyttet. Hvis du ønsker at brukere skal kunne overstyre verdien manuelt, kan du legge til en inverse-metode som oversetter brukerskrevne verdier tilbake til kildefeltene. Dette er nyttig når automatisk verdi er et godt utgangspunkt, men noen ganger må kunne endres.
Odoo Studio-felt og XML-RPC API
Teams som administrerer felt via XML-RPC kan opprette standardfelter gjennom ir.model.fields. For beregnet logikk som krever Python må compute-funksjonen likevel ligge i servermodulen. API-et er praktisk for å provisionere enkle felt, men komplisert logikk trenger en installert modul.
Gode fremgangsmåter
Her er fremgangsmåtene erfarne Odoo-konsulenter følger for lagrede beregnede felt.
Spesifiser alle avhengigheter nøyaktig
I @api.depends() må du liste hvert felt compute-metoden leser. Glemmer du en avhengighet, vil feltet ikke oppdatere når den endres. Les koden linje for linje og noter alle felttilgangene i dekoratøren.
Hold compute-metodene raske
Compute-metoden kan bli kalt for mange poster samtidig. Unngå ekstra databaseoppslag inne i løkken. Bruk allerede tilgjengte felter og batch-operasjoner for å minimere antall spørringer.
Bruk store=True kun når nødvendig
Lagrede felt tar plass og skriver til databasen ved hver recompute. Hvis feltet kun skal vises i et skjema og ikke brukes i søk eller rapporter, velg ikke-lagret for å spare ressurser.
Håndter kanttilfeller i compute-metoden
Ta høyde for tomme verdier, nuller og manglende relasjoner. Deling på null og ikke-eksisterende relasjoner er vanlige feilkilder — legg inn eksplisitte sjekker og trygge standardverdier.
Planlegg initial recompute for store tabeller
Ved installasjon vil Odoo rekalkulere feltet for alle eksisterende rader. På store tabeller kan dette ta lang tid. Test migrasjon i staging og planlegg for bakgrunnsbehandling eller vinduer for deploy.
Unngå sirkulære avhengigheter
Hvis felt A avhenger av B og B avhenger av A, vil Odoo feile ved lasting. Design avhengighetene slik at de flyter i én retning.
Vanlige fallgruver
Glemme store=True
Dette er den vanligste feilen. Feltet vises fint i skjema, men fungerer ikke i filtre eller rapporter. Bestem tidlig om feltet må være søkbart, og sett store=True hvis det er nødvendig.
Mangle en avhengighet i @api.depends
Hvis compute-metoden leser partner_id.country_id men dekoratøren kun nevner partner_id, oppdateres ikke feltet når landfeltet endres. Spor hele sti-tilgangen og list alle steg i dekoratøren.
Stille feil i compute-metoden
Om compute-metoden kaster et unntak for en post, hopper Odoo over oppdateringen for den posten og beholder tidligere lagrede verdi. Feilen kan kun dukke opp i loggene og føre til utdaterte resultater. Test alltid mot poster med uvanlige eller manglende data.
Ytelsesproblemer ved store datasett
En metode som fungerer i utvikling kan bli flaskehals i produksjon når antall rader vokser. Vær bevisst på hvor mange spørringer compute-metoden utløser per post — ett ekstra søk per rad kan eskalere voldsomt.
Bruke sudo() inne i compute-metoder
Å bruke sudo() for å omgå tilgangskontroll i compute-metoder er en sikkerhetsrisiko. Da kan sensitiv informasjon eksponeres for brukere som ikke skal se den. Bruk sudo() kun etter nøye vurdering av konsekvensene.
Forvent ikke umiddelbar recompute i alle kontekster
I interaktive operasjoner skjer recompute ofte synkront, men ved import, bakgrunnsjobber eller ved visse kontekstflagg kan Odoo utsette beregningen. Bygg ikke forretningslogikk som forutsetter umiddelbar oppdatering uten å verifisere konteksten.
Avslutning
Lagrede beregnede felt er et av de mest praktiske verktøyene i Odoo: de automatiserer beregninger, holder data konsistente og gjør informasjon søkbar og eksportklar uten manuell innsats.
Hovedpunktene å ta med deg:
- Bruk
store=Truenår feltet må være søkbart, filtrerbart eller eksportbart. - Oppgi alltid alle avhengigheter i
@api.depends(), også tvers av modeller. - Hold compute-metoder raske og håndter kanttilfeller eksplisitt.
- For enkle formler er Odoo Studio raskt. For komplisert logikk, skriv Python.
- Planlegg initial recompute ved utrulling til produksjon på store tabeller.
Enten du lager en modul fra bunnen, utvider en eksisterende modell, eller lærer deg Odoo-felttyper, er lagrede beregnede felt viktige å forstå. De forbinder ORM, databasen og forretningslogikken.
Trenger du hjelp med Odoo-implementasjonen?
Dasolo bistår selskaper med implementasjon, tilpasning og optimalisering av Odoo for ulike behov. Enten du trenger beregnede felt, rapporter basert på kalkulerte verdier eller videre Odoo-utvikling, har teamet erfaringen du trenger.
Ta kontakt om du trenger støtte i prosjektet ditt. Vi tar gjerne en prat om ditt behov og finner riktig løsning for virksomheten.