Introductie
Binary-velden zijn geen showstoppers, maar ze zitten overal zodra een Odoo-omgeving écht gebruikt wordt. Telkens iemand een ondertekend contract uploadt, een productsheet toevoegt of het bedrijfslogo op een fiche plaatst, staat er een Binary-veld achter de schermen te werken. Weten hoe die data wordt opgeslagen, waar ze terechtkomt en wanneer je beter een ander veldtype gebruikt, voorkomt verrassingen bij het bouwen van formulieren of uitbreidingen.
Deze gids legt uit wat een Binary-veld precies bewaart, hoe de keuze voor attachment de opslag en prestaties beïnvloedt, hoe je hetveld toevoegt met Odoo Studio of in Python, en geeft concrete voorbeelden uit CRM, HR, voorraadbeheer en andere afdelingen.
Wat is het Binary-veld in Odoo
Binnen de Odoo ORM is een Binary-veld (fields.Binary) bedoeld om ruwe binaire inhoud te bewaren: documenten, afbeeldingen of andere bestanden die gebruikers koppelen aan een record. Voor de gebruiker verschijnt dit als een uploadknop in een formulier, en na het toevoegen fungeert diezelfde knop als downloadlink.
De cruciale technische nuance is wáár de bytes terechtkomen. In moderne Odoo-versies werken Binary-velden standaard met attachment-mode: de inhoud wordt als bijlage in de ir.attachment-tabel en in het filestore op de server bewaard. Het veld in het model bevat dan enkel nog een referentie naar die bijlage. Die opzet zorgt voor slankere tabellen en efficiëntere bestandsafhandeling.
In Odoo Studio vind je het Binary-veld terug als het File-veld in de veldkiezer. In formulieren geeft het een eenvoudige upload/downloadcontrole. Voor afbeeldingen bestaat er trouwens een speciaal type fields.Image met automatische resizing en preview — daarover meer verderop.
Een Binary-veld definieer je in Python als onderdeel van je model, waarna Odoo het nodige aanmaakt in de database bij installatie of update.
Voorbeeld van hoe je het in een model zet (vereenvoudigd):
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
x_signed_contract = fields.Binary(
string='Signed Contract',
attachment=True,
)
x_signed_contract_filename = fields.Char(
string='Signed Contract Filename',
)
Let op het bijhorend x_signed_contract_filename-veld. Het is een courante praktijk om een Char-veld met suffix _filename te voorzien zodat de interface de originele bestandsnaam kan weergeven bij downloaden. Zonder zo'n veld krijgen gebruikers vaak een generieke naam.
Hoe het veld werkt
Wanneer je een Binary-veld toevoegt in het datamodel zorgt Odoo automatisch voor de nodige kolommen en migraties bij module-installatie of -upgrade; je hoeft geen handmatige SQL-scripts te schrijven.
Opslagmodi
Met de attachment-parameter bepaal je waar de eigenlijke bytes worden bewaard:
- attachment=True (aanbevolen): de bestandsinhoud gaat naar ir.attachment en wordt gelinkt aan het record via modelnaam en ID. Het modelveld zelf bevat enkel een referentie. Dit houdt je databasetabellen compact en maakt gebruik van Odoo's filestore.
- attachment=False: de base64-gecodeerde inhoud wordt direct in de kolom van het model opgeslagen. Daardoor kunnen tabellen snel opzwellen en queries vertragen. Gebruik dit niet voor bestanden groter dan een kleine thumbnail.
Dataformaat
Binary-velden werken met base64: ze bewaren en retourneren base64-gecodeerde bytes. Lees je het veld via de ORM of XML-RPC, dan krijg je een base64-string; schrijf je naar het veld, dan moet je ook een base64-string aanleveren.
Praktisch betekent dit dat je gaat encoden bij schrijven en decoden bij lezen.
Concreet voorbeeld in Python:
import base64
# Bestand schrijven naar Binary-veld
with open('document.pdf', 'rb') as f:
encoded = base64.b64encode(f.read()).decode('utf-8')
record.write({'x_signed_contract': encoded})
# Bestand lezen uit Binary-veld
raw_bytes = base64.b64decode(record.x_signed_contract)
Belangrijke veldattributen
Dit zijn de configuraties die je het meest zal gebruiken bij een Binary-veld in Odoo:
- attachment: Boolean. Bepaalt opslag in ir.attachment (True) of direct in de kolom (False). Standaard: True in recente Odoo-versies.
- string: Label dat in de UI wordt getoond.
- required: Maakt het veld verplicht voor het opslaan van een record.
- compute: Koppelt een Python-methode die het veld dynamisch berekent — denk aan het on-the-fly genereren van een PDF.
- store: Gebruik je met compute om de berekende waarde in de database op te slaan.
- groups: Beperk toegang tot bepaalde gebruikersgroepen, cruciaal voor gevoelige documenten.
- copy: Bepaalt of de waarde gekopieerd wordt bij dupliceren van een record; gedrag varieert met attachment-mode en Odoo-versie.
De fields.Image-subklasse
fields.Image is sinds Odoo 13 een gespecialiseerde vorm van Binary voor afbeeldingen. Het voegt automatische resizing, optionele preview-dimensies en een echte thumbnail-weergave toe in formulieren. Voor productfoto's, portretten of logo's gebruik je dus beter fields.Image: dat voorkomt gigantische uploads en verbetert de gebruikerservaring aanzienlijk.
Weergave in views
In een formulier is het standaardwidget voor Binary een upload-/downloadknop. Voor afbeeldingen gebruik je het image-widget voor een thumbnail. In lijstweergaven toon je doorgaans geen volledige Binary-velden — dat zou per rij grote hoeveelheden data laden. Gebruik daar eerder een indicator-veld of icoon om aan te geven of een bestand aanwezig is.
Praktische bedrijfsgevallen
Binary-velden komen in bijna elk Odoo-project voor. Hieronder vijf concrete voorbeelden uit alledaagse workflows.
CRM: Ondertekende NDA's of contracten bij klantfiches
Verkoopteams willen vaak het ondertekende contract direct op de klantfiche terugvinden. Een Binary-veld op res.partner of crm.lead biedt één klik toegang tot het document binnen Odoo, zonder aparte DMS. Dat houdt alles op één plek tijdens het verkoopproces.
HR: Personeelsdocumenten bewaren
HR bewaart ID-bewijzen, arbeidsovereenkomsten, verblijfsvergunningen en certificaten. Een Binary-veld op hr.employee plaatst die bestanden binnen Odoo's toegangsregels. Met het groups-attribuut beperk je wie de documenten kan zien — bijvoorbeeld alleen HR-managers — wat helpt bij privacy- en compliance-eisen.
Voorraad: Productsheets en veiligheidsdocumenten
Producten hebben vaak PDF-specificaties, veiligheidsfiches of kwaliteitscertificaten. Een Binary-veld op product.template stelt aankoop en magazijn in staat om snel de juiste documenten te raadplegen vanuit het productrecord. Dit is een veelgevraagde aanpassing in productie- en distributiebedrijven en eenvoudig implementeerbaar via Studio of een module.
Verkoop: Bedrijfstempel of handtekening voor documenten
Sommige bedrijven plaatsen een stempel of handtekening op offertes en bestelbevestigingen. Een fields.Image op res.company bewaart dat beeldbestand zodat QWeb-rapporten automatisch de stempel tonen. Dat scheelt handmatig werk en voorkomt dat ongetekende documenten de deur uitgaan.
Boekhouding: Ingescande bonnetjes bij onkostennota's
Bij onkosten is het gebruikelijk een gescand bonnetje of factuur te koppelen als bewijs. Standaard werkt Odoo met attachments, maar voor custom onkostenmodellen of integraties is een Binary-veld een nette manier om het PDF- of afbeeldingsbestand bij het record te bewaren en mee te nemen in goedkeuringsstromen.
Een Binary-veld aanmaken of aanpassen
Er zijn drie gangbare manieren om een Binary-veld aan een model toe te voegen, afhankelijk van je technische situatie en gewenste controle.
Via Odoo Studio (zonder code)
Odoo Studio is de low-code tool waarmee je snel velden toevoegt. Zo voeg je een Binary-veld toe zonder te programmeren:
- Open Odoo Studio vanuit het hoofdmenu.
- Ga naar het formulier waar je het veld wilt laten verschijnen.
- Sleep in de veldkiezer het File-veld naar je formulier.
- Stel label en zichtbaarheid in het eigenschappenpaneel in.
- Sla op en sluit Studio.
Studio maakt het veld met een x_studio_-prefix en gebruikt attachment-mode. Je hoeft niets in de database aan te passen. Voor businessgebruikers is dit de snelste manier om file-uploads in formulieren toe te voegen.
Via Python in een custom module
Wanneer je versiebeheer, herbruikbaarheid en gecontroleerde deploys nodig hebt, definieer je Binary-velden in Python binnen een module — de aanbevolen aanpak voor serieuze aanpassingen.
Voorbeeld in een HR-context:
from odoo import fields, models
class HrEmployee(models.Model):
_inherit = 'hr.employee'
x_id_document = fields.Binary(
string='ID Document',
attachment=True,
groups='hr.group_hr_user',
)
x_id_document_filename = fields.Char(
string='ID Document Filename',
)
Na toevoeging plaats je het veld in de form-view XML met widget="binary" en filename verwijzend naar het bijhorend Char-veld. Odoo regelt de databasekolom bij installatie of upgrade. Deze methode werkt netjes op Odoo.sh en on-premise omgevingen.
Via de XML-RPC API
Als je veldcreatie wilt automatiseren vanuit een script of deployment-notebook, kun je velden aanmaken via XML-RPC:
Voorbeeldcall die een binaire velddefinitie creëert:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_custom_document',
'field_description': 'Custom Document',
'model_id': model_id,
'ttype': 'binary',
'state': 'manual',
}]
)
state: 'manual' geeft aan dat het veld handmatig is aangemaakt in plaats van via een module. Velden gemaakt via de API gebruiken in recente Odoo-versies standaard attachment-mode — handig voor geautomatiseerde configuraties.
Aanbevolen werkwijzen
1. Gebruik altijd attachment=True
Opslaan in ir.attachment is in vrijwel alle gevallen de juiste keuze. Het houdt tabellen slank, voorkomt traagheid bij queries en laat Odoo het filestore beheren. Voor elk bestand groter dan een kleine thumbnail is attachment-mode essentieel.
2. Voorzie altijd een char-veld voor de bestandsnaam
Koppel een companion _filename Char-veld aan elk Binary-veld dat gebruikers kunnen downloaden. Zonder dat zien gebruikers bij het downloaden vaak een onduidelijke bestandsnaam. Deze kleine toevoeging verbetert de UX aanzienlijk.
3. Gebruik fields.Image voor visuele inhoud
Voor productfoto's, logo's en profielfoto's gebruik je fields.Image. Het beperkt afmetingen, levert thumbnails en voorkomt dat gebruikers grote beelden uploaden die formulieren vertragen. Kies het veldtype dat past bij het verwachte inhoudstype.
4. Beperk toegang met groups
Voor vertrouwelijke documenten (arbeidsovereenkomsten, contracten, financiële stukken) definieer je zichtbaarheid met het groups-attribuut. Zo bepaal je wie mag lezen of schrijven, cruciaal voor privacy en audits.
5. Ga correct om met base64 in code
Bij programmatig lezen of schrijven altijd expliciet encoden/decoden: gebruik base64.b64encode(file_bytes).decode('utf-8') bij schrijven en base64.b64decode(value) bij lezen. Het foutief aannemen van het formaat is een veelvoorkomende bron van bugs.
Veelvoorkomende valkuilen
Gevaar van attachment=False bij grote bestanden
Bestanden direct in een databasekolom opslaan kan je PostgreSQL-tabellen flink doen groeien. Enkele tientallen PDF's met attachment=False kunnen honderden megabytes extra in één tabel opleveren en daarmee de prestaties van alle queries op dat model schaden. Migreren naar attachment-mode vereist daarna een zorgvuldige, vaak complexe migratiescript.
Het vergeten van het filename-veld
Zonder companion Char-veld voor de bestandsnaam krijgen gebruikers generieke downloadnamen. Het ziet er onaf uit en is eenvoudig te verhelpen: voeg dat veld altijd toe als het Binary-veld in een gebruikersformulier staat.
Binary en Image door elkaar halen
Een plain Binary-veld voor afbeeldingen mist resizing en thumbnails van fields.Image, wat kan leiden tot te grote uploads. Omgekeerd veroorzaakt fields.Image fouten als je er geen afbeeldingsbestand in stopt. Houd het juiste veldtype bij het verwachte bestandstype.
Binary-velden direct in lijstweergaven tonen
Plaats je een Binary-veld in een list view, dan probeert Odoo per rij content te laden — bij vijftig rijen kunnen dat megabytes data worden. Gebruik in lijsten een berekend boolean-veld of een icoon om aanwezigheid te tonen in plaats van het volledige Binary-veld.
Niet checken op False voor verwerking in code
Een leeg Binary-veld geeft in Python False terug, niet een lege string of lege bytes. Probeer je zonder check te decoderen, dan krijg je een TypeError. Voorbeeldguard: if record.x_document: data = base64.b64decode(record.x_document). Deze controle voorkomt crashes in compute-methodes, server-acties en integraties.
Samenvatting
Het Binary-veld is een eenvoudig maar essentieel onderdeel van het Odoo-datamodel. Het zorgt voor integratie van bestanden binnen de interface, het attachment-systeem en de toegangscontrole.
De belangrijkste gewoontes: gebruik altijd attachment-mode, koppel een filename Char-veld, zet images in fields.Image, beperk toegang met groups en ga zorgvuldig om met base64-encoding. Met die regels voorkom je de meest voorkomende problemen voordat ze in productie opduiken.
Of je nu een file-upload toevoegt met Odoo Studio, een module bouwt in Python of velden beheert via de ORM of XML-RPC: goed begin met Binary-velden levert een schonere en betrouwbaardere Odoo-implementatie op.
Bij Dasolo helpen we organisaties met implementatie, maatwerk en optimalisatie van Odoo voor alle afdelingen. Of het nu gaat om datamodeladvies, file-management workflows of volledige module-ontwikkeling, ons team ondersteunt je graag. Contacteer ons en laten we jouw Odoo-project bespreken.