Inleiding
De meeste Odoo-ontwikkelaars grijpen naar het Many2one-veld wanneer ze een record aan een ander record moeten koppelen. Het werkt perfect in de overgrote meerderheid van de gevallen. Maar soms kom je in een situatie terecht waarin het gelinkte document een van verschillende dingen kan zijn: een verkooporder, een inkooporder, een productieorder, of iets heel anders, afhankelijk van de context. Dat is precies waarvoor het Referentieveld is ontworpen.
Het Referentieveld is een van de flexibelere veldtypes in de Odoo ORM. Het stelt je in staat om een link naar een record van elk model in een vooraf gedefinieerde lijst te maken, in plaats van altijd naar hetzelfde model te wijzen. De gebruiker selecteert eerst het documenttype en kiest vervolgens het specifieke record. Het resultaat is een polymorfe link die zich kan aanpassen aan verschillende workflows.
Deze gids behandelt wat het Referentieveld opslaat, hoe het zich gedraagt in het Odoo-datamodel, hoe je het kunt maken en aanpassen met Odoo Studio of Python, en praktische zakelijke gebruikscases waar het echt waarde toevoegt.
Wat is het Referentieveld in Odoo
In de Odoo ORM is het Referentieveld een speciaal veldtype dat een link naar een record van elk model opslaat dat je in zijn selection lijst opneemt. Dit maakt het fundamenteel anders dan een Many2one-veld, dat altijd naar één vast model wijst.
In de database slaat het Referentieveld zijn waarde op als een gewone tekststring in het formaat model_name,record_id. Bijvoorbeeld, een verwijzing naar verkooporder nummer 42 zou worden opgeslagen als sale.order,42. Dit is belangrijk om te begrijpen als je ooit deze records rechtstreeks moet opvragen of filteren.
Vanuit het perspectief van de gebruikersinterface verschijnt een Referentieveld als een invoer in twee stappen. De gebruiker selecteert eerst een documenttype uit een dropdownlijst (bijvoorbeeld: Verkooporder, Factuur of Projecttaak), en kiest vervolgens het specifieke record uit dat model met behulp van een zoekveld. De interface is schoon en eenvoudig zodra gebruikers de selectie in twee stappen begrijpen.
Hier is hoe een basisdefinitie van een Referentieveld eruitziet in Python:
from odoo import fields, models
class HelpDeskTicket(models.Model):
_inherit = 'helpdesk.ticket'
related_document = fields.Reference(
selection=[
('sale.order', 'Verkooporder'),
('purchase.order', 'Inkooporder'),
('account.move', 'Factuur'),
('project.task', 'Projecttaak'),
],
string='Gerelateerd Document',
)
De selection parameter is een lijst van tuples. Elke tuple bevat de technische modelnaam (zoals sale.order) en het leesbare label dat gebruikers in de dropdown zullen zien. Je bepaalt precies welke modellen beschikbaar zijn in deze lijst.
Er is ook een dynamische variant waarbij de selectielijst tijdens runtime wordt gevuld vanuit de ir.model tabel, waardoor alle geïnstalleerde modellen beschikbaar zijn. Dit is nuttig voor zeer configureerbare tools, maar kan overweldigend worden voor eindgebruikers als het niet goed gefilterd is.
In Odoo Studio is het Referentieveld beschikbaar onder het paneel voor veldtypes en gelabeld als Referentie. Wanneer je het via Studio toevoegt, kun je de lijst van selecteerbare modellen rechtstreeks vanuit de interface configureren zonder enige code te schrijven. Dit maakt het een van de toegankelijkere opties onder de geavanceerde Odoo-studio-velden.
Hoe het Veld Werkt
Begrijpen hoe het Referentieveld gegevens opslaat en ophaalt, is de sleutel tot het correct gebruiken ervan in je Odoo-ontwikkelingsprojecten.
Opslag in de Database
In tegenstelling tot een Many2one-veld, dat alleen een geheel getal (de vreemde sleutel) opslaat, slaat het Referentieveld een stringwaarde op die zowel de modelnaam als de record-ID bevat. Bijvoorbeeld: sale.order,15. Dit wordt opgeslagen in een VARCHAR kolom in PostgreSQL. Dit betekent dat de database geen vreemde-sleutelbeperkingen op deze kolom afdwingt, wat een opzettelijke ontwerpkeuze is om de polymorfe aard van het veld te ondersteunen.
Omdat er geen vreemde sleutel op database-niveau is, ruimt Odoo de waarden van het Referentieveld niet automatisch op wanneer het gekoppelde record wordt verwijderd. Als een verkooporder wordt verwijderd, bevat een Referentieveld dat naar deze verwijst nog steeds de oude stringwaarde. Dit is een van de belangrijkste gedragsverschillen om in gedachten te houden tijdens de Odoo-ontwikkeling.
Toegang tot het Gelinkte Record in Python
Wanneer je een Referentieveldwaarde in Python leest, retourneert Odoo het daadwerkelijke recordobject van het verwezen model. Je kunt de velden direct benaderen, net zoals je zou doen met een Many2one-resultaat. Als het veld leeg is, retourneert het False.
ticket = self.env['helpdesk.ticket'].browse(1)
doc = ticket.related_document
if doc:
print(doc._name) # bijv. 'sale.order'
print(doc.name) # bijv. 'S00042'
print(doc.id) # bijv. 15
Dit is een van de handige aspecten van de Odoo ORM-abstractie. Hoewel de onderliggende opslag een gewone tekststring is, lost het framework dit op naar een juist recordobject wanneer je er in de code toegang toe krijgt.
Belangrijke Veldattributen
Dit zijn de meest relevante attributen die je kunt configureren op een Referentieveld in het Odoo-framework:
- selection: Een lijst van tuples die definieert welke modellen selecteerbaar zijn. Kan ook een methodenaam (string) zijn die zo'n lijst dynamisch retourneert.
- string: Het veldlabel dat aan gebruikers in de interface wordt getoond.
- required: Maakt het veld verplicht. De gebruiker moet zowel een modeltype als een record selecteren voordat hij opslaat.
- readonly: Voorkomt dat gebruikers de veldwaarde vanuit de interface wijzigen. Handig wanneer de referentie programmatisch is ingesteld.
- help: Een tooltip die wordt weergegeven wanneer de gebruiker over het veldlabel zweeft. Handig om gebruikers te begeleiden bij wat ze moeten selecteren.
- compute: Zoals elk ander Odoo-veldtype kan een Referentieveld dynamisch worden berekend met behulp van een Python-methode. Dit is nuttig voor het automatisch instellen van een referentie op basis van bedrijfslogica.
Filteren en Zoeken
Omdat de waarde als een gewone string is opgeslagen, vereist het filteren op een Referentieveld specifieke domeinsyntaxis. Om records te zoeken die aan een specifiek document zijn gekoppeld, moet je de stringwaarde zelf samenstellen:
tickets = self.env['helpdesk.ticket'].search([
('related_document', '=', 'sale.order,15')
])
Je kunt ook filteren op modeltype met behulp van een like operator:
tickets = self.env['helpdesk.ticket'].search([
('related_document', 'like', 'sale.order,')
])
Houd dit stringgebaseerde filtergedrag in gedachten bij het ontwerpen van rapporten of berekende velden die afhankelijk zijn van waarden van het Referentieveld. Het gedraagt zich anders dan een typische Many2one domeinfiler.
Zakelijke Gebruikscases
Het Referentieveld is het meest waardevol in situaties waarin dezelfde soort contextlink naar documenten van verschillende types kan wijzen, afhankelijk van de situatie. Hier zijn vijf praktische voorbeelden uit echte bedrijfsworkflows.
1. Helpdesk Tickets Koppelen aan Elk Document
Een supportteam behandelt tickets die met heel verschillende zaken te maken kunnen hebben: een factuurgeschil, een leveringsprobleem, een contractvraag of een defect product. In plaats van een apart veld voor elk documenttype te creëren, laat een enkel Referentieveld op het ticketmodel de agent toe om te koppelen aan welk document dan ook dat relevant is. De agent kiest eerst het type (Factuur, Verkooporder, Levering, enz.) en kiest dan het specifieke record. Alle context bevindt zich in één veld.
2. CRM Activiteiten Koppelen aan Meerdere Brondocumenten
In een verkoopteam ontstaan activiteiten en opvolgtaken soms vanuit verschillende bronnen: een lead, een offerte, een bestaand contract of een supportcase. Een Referentieveld op een aangepast activiteitsmodel of CRM-notitie laat verkopers toe om het oorsprongsdocument te taggen zonder vast te zitten aan een enkel model. Dit is een natuurlijke aanvulling voor het Referentieveld in een Odoo CRM-aanpassing.
3. Notities en Annotaties Over Modules
Sommige bedrijven bouwen een eenvoudig intern notities- of annotatiemodel om observaties vast te leggen over verschillende bedrijfsobjecten. Een Referentieveld stelt een enkele notitie-record in staat om aan een klantrecord, een projecttaak, een productieorder of een inkooporder te worden gekoppeld, allemaal binnen hetzelfde veld. Dit voorkomt het dupliceren van het notitiemodel voor elk documenttype.
4. Documentgoedkeuringsworkflow
Bij het implementeren van een generieke goedkeuringsworkflow moet de goedkeuringsaanvraag verwijzen naar het document dat goedgekeurd wordt. Aangezien goedkeuringen van toepassing kunnen zijn op inkooporders, onkostennota's, verlofaanvragen of contracten, houdt een Referentieveld op het goedkeuringsmodel de architectuur schoon. Dezelfde goedkeuringslogica behandelt alle documenttypes zonder dat er aparte modellen voor elk nodig zijn.
5. Onkostennota's gekoppeld aan projecten of klantorders
In sommige boekhoudinstellingen moet een onkostenpost worden gekoppeld aan ofwel een klantproject of een verkooporder, afhankelijk van de aard van de kosten. Een Referentieveld met zowel project.project als sale.order in de selectie lijst geeft de accountant de flexibiliteit om de onkosten aan het toepasselijke document te koppelen. Dit is bijzonder nuttig in professionele diensten en adviesbureaus die Odoo gebruiken.
Een Referentieveld Maken of Aanpassen
Er zijn twee hoofdmethoden om een Referentieveld aan een Odoo-model toe te voegen: met Odoo Studio voor een no-code benadering, of door het rechtstreeks in Python te schrijven voor volledige controle.
Odoo Studio gebruiken
Odoo Studio maakt het eenvoudig om een Referentieveld aan elk formulier toe te voegen zonder code aan te raken. Open Studio op het model dat je wilt uitbreiden, ga naar het veldenpaneel en voeg een nieuw veld van het type Referentie toe. Je wordt gevraagd om te selecteren welke modellen in de dropdownlijst moeten verschijnen. Studio slaat het veld op als een handmatig veld met een x_ voorvoegsel, net als andere Odoo-studio-velden die via de interface zijn gemaakt.
Deze benadering is ideaal voor snelle aanpassingen en voor businessanalisten die formulieren willen uitbreiden zonder betrokkenheid van ontwikkelaars. Houd er rekening mee dat Referentievelden die met Studio zijn gemaakt, mogelijk beperkte ondersteuning hebben voor geavanceerde configuraties zoals dynamische selectiemethoden of berekende waarden.
Technische implementatie in Python
Voor een volledige Odoo-ontwikkelingsbenadering, definieer het Referentieveld rechtstreeks in een Python-model. Hier is een completer voorbeeld dat laat zien hoe je een Referentieveld met een dynamische selectiemethode kunt maken:
from odoo import api, fields, models
class ApprovalRequest(models.Model):
_name = 'approval.request'
_description = 'Approval Request'
name = fields.Char(string='Request Name', required=True)
@api.model
def _get_document_types(self):
return [
('purchase.order', 'Purchase Order'),
('hr.expense.sheet', 'Expense Report'),
('hr.leave', 'Time Off Request'),
('sale.order', 'Sale Order'),
]
document_ref = fields.Reference(
selection='_get_document_types',
string='Document',
help='Select the document this approval relates to.',
)
Het gebruik van een methode voor de selection parameter (door de naam als een string door te geven) geeft je meer flexibiliteit. Je kunt voorwaardelijke logica toevoegen, filteren op basis van geïnstalleerde modules, of de lijst dynamisch opbouwen vanuit configuratieregisters.
Creëren via de XML-RPC API
Je kunt ook een Referentieveld programmatisch aanmaken met behulp van de Odoo XML-RPC API. Dit is nuttig bij het implementeren van velden als onderdeel van een externe configuratienotitieboek. Het veldtype dat je moet gebruiken is reference en de selectie wordt doorgegeven als een stringrepresentatie van de lijst:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_related_document',
'field_description': 'Gerelateerd Document',
'model_id': model_id,
'ttype': 'reference',
'selection': "[('sale.order', 'Verkooporder'), ('purchase.order', 'Inkooporder')]",
'state': 'manual',
}]
)
Let op dat wanneer je een Referentieveld via de API aanmaakt, de selection waarde wordt doorgegeven als een Python-evalueerbare string in plaats van een daadwerkelijke lijst. Dit is hoe Odoo het opslaat en leest vanuit de ir.model.fields tabel.
Beste Praktijken
Hier zijn de meest nuttige richtlijnen om te volgen bij het werken met Referentievelden in je Odoo-datamodel.
- Houd de selectielijst kort en betekenisvol. Neem niet elk model op alleen omdat je dat kunt. Beperk de lijst tot de documenttypes die echt zinvol zijn voor de use case. Een lange lijst verwart gebruikers en maakt het veld moeilijker correct te gebruiken.
- Gebruik Many2one wanneer je altijd naar hetzelfde model linkt. Het Referentieveld is ontworpen voor polymorfe relaties. Als het gelinkte model nooit verandert, is een standaard Many2one-veld eenvoudiger, sneller te doorzoeken en beter ondersteund door Odoo-rapportagetools.
- Controleer altijd op null-waarden in berekende velden. Wanneer een Referentieveld leeg is, retourneert het
Falsein Python. Elke code die toegang heeft tot het gelinkte record moet dit eerst controleren om fouten te voorkomen. - Behandel weesverwijzingen in geautomatiseerde acties. Aangezien de database geen referentiële integriteit afdwingt op Referentievelden, is het een goed idee om een geautomatiseerde actie of een geplande actie toe te voegen die periodiek controleert op en verouderde verwijzingen naar verwijderde records opruimt.
- Gebruik beschrijvende labels voor elk model in de selectie. Het tweede element van elke tuple is wat gebruikers zien in de dropdown. Gebruik duidelijke, zakelijke labels in plaats van technische modelnamen. Schrijf "Klantfactuur" in plaats van "account.move".
- Documenteer het veld duidelijk in je technische specificaties. Omdat Referentievelden zich anders gedragen dan standaard Many2one-velden, zal elke ontwikkelaar die jouw code overneemt profiteren van een duidelijke uitleg over waarom een Referentie is gekozen en welke modellen eraan zijn gekoppeld.
Veelvoorkomende Valkuilen
Dit zijn de fouten die we het vaakst zien wanneer ontwikkelaars of businessanalisten voor de eerste keer met Referentievelden werken.
Het behandelen als een Many2one in Domeinfilters
Ontwikkelaars schrijven soms domeinfilters voor een Referentieveld met dezelfde syntaxis als een Many2one, bijvoorbeeld [('document_ref', '=', 15)]. Dit zal niet werken. De opgeslagen waarde is een string zoals sale.order,15, niet alleen een geheel getal. Je moet de volledige stringwaarde samenstellen bij het bouwen van domeinfilters op een Referentieveld.
Vergeten dat Verwijderde Records Weeswaarden Achterlaten
Omdat er geen foreign key-constraint in de database is, verwijdert het verwijderen van een verwezen record de waarde van het Referentieveld niet. Als een verkooporder wordt verwijderd en een ticket nog steeds sale.order,42 in zijn Referentieveld heeft, zal het lezen van dat veld False retourneren in plaats van een fout te genereren. Code die afhankelijk is van de geldigheid van de referentie moet altijd met deze situatie rekening houden.
Overmatig gebruik van de Dynamische All-Models Selectie
Odoo staat je toe een methode voor de selection door te geven die alle geïnstalleerde modellen uit ir.model retourneert. Hoewel dit krachtig is, is het bijna altijd te breed voor een gebruikersveld. Het presenteren van honderden modellen in een dropdown is verwarrend en leidt tot onjuiste gegevensinvoer. Beperk de selectie altijd tot een zorgvuldig samengestelde lijst van betekenisvolle documenttypes.
Verwachten van Natuurlijke Groepering in Rapporten
Referentievelden worden als platte tekststrings in de database opgeslagen. Ze zijn geen foreign keys, dus de standaard Odoo groepering en pivot-functionaliteit werkt niet op hen zoals het dat doet op Many2one-velden. Als je records moet groeperen of aggregeren op basis van hun gekoppelde document, moet je dit afhandelen via aangepaste code of een berekend veld dat de modelnaam als een aparte selectie of char-veld extraheren.
Verwarring tussen Referentie en Many2one in Odoo Studio
Bij het gebruik van Odoo Studio verwarren sommige gebruikers het Referentieveld en het Many2one-veld omdat beide je in staat stellen om naar een ander record te linken. Het belangrijkste verschil is dat een Many2one altijd naar één specifiek model linkt (je kiest het bij het aanmaken van het veld en het verandert nooit), terwijl een Referentieveld de gebruiker toestaat om elk keer het model te kiezen wanneer ze het veld invullen. Als je een Many2one hebt gemaakt terwijl je een Referentie nodig had, moet je het veld opnieuw opbouwen in plaats van te proberen het bestaande aan te passen.
Conclusie
Het Referentieveld vult een leemte die het Many2one-veld niet alleen kan dekken. Wanneer een link flexibel genoeg moet zijn om naar verschillende documenttypes te wijzen, afhankelijk van de situatie, is het Referentieveld het juiste hulpmiddel in het Odoo-framework. Het is eenvoudig te definiëren, werkt met Odoo Studio voor no-code setups, en integreert natuurlijk in Python-modellen voor technische implementaties.
De belangrijkste zaken om in gedachten te houden zijn het op strings gebaseerde opslagformaat, de afwezigheid van automatische opruiming van buitenlandse sleutels, en de noodzaak om te filteren met samengestelde stringwaarden in plaats van eenvoudige ID's. Zodra je die verschillen begrijpt, gedraagt het veld zich voorspelbaar en betrouwbaar binnen je Odoo-datamodel.
Of je nu een generieke goedkeuringsworkflow bouwt, ondersteuningsverzoeken aan verschillende documenttypen koppelt, of een flexibel notitiesysteem ontwerpt dat meerdere modules beslaat, het Referentieveld biedt je een schone en onderhoudbare oplossing zonder dat je je logica voor elk modeltype hoeft te dupliceren.
Hulp Nodig bij Uw Odoo Implementatie?
Bij Dasolo helpen we bedrijven bij het implementeren, aanpassen en optimaliseren van Odoo om aan hun werkelijke bedrijfsworkflows te voldoen. Of je nu aangepaste veldlogica moet bouwen, een datamodel vanaf nul moet ontwerpen, of een bestaande Odoo-opstelling wilt uitbreiden met nieuwe functionaliteit, ons team heeft de technische diepgang om het goed te doen.
Als je aan een Odoo-project werkt en begeleiding nodig hebt over veldtypes, data-architectuur of ontwikkelingsbest practices, aarzel dan niet om contact op te nemen. We bespreken graag je situatie en helpen je de juiste aanpak te vinden.