reference
One field, two questions: which model, then which record. reference is the widget behind that pair of inputs, and it accepts far more options than it admits to.
| Technical name | reference |
|---|---|
| Field types | reference, char |
| Views | form, list, and inside x2many subviews |
| Module | web, present in every Odoo database |
| Used in core | 1 direct usage in core views, in snailmail, but the widget is the default renderer for every reference field |
| Versions | Odoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0 |
| No-code setup | No. Studio has no Reference field type, so both the field and the widget are XML work |
| Alternatives | many2one, selection, char |
What the reference field does
What this means for your team
Supported options in Odoo 19
| Option | Type | What it does |
|---|---|---|
hide_model | boolean | Hides the model dropdown and keeps only the record autocomplete. Use it when the model is fixed by context or by a default value.(default: false) |
model_field | field | Name of a many2one to ir.model on the same record. The widget reads the technical model name from it and hides the selector. Anything that is not a many2one to ir.model raises an explicit error. |
no_open | boolean | <strong>Inherited and undeclared.</strong> Removes the internal link that opens the referenced record.(default: false) |
no_create | boolean | <strong>Inherited and undeclared.</strong> Removes both creation paths from the record autocomplete.(default: false) |
no_quick_create | boolean | <strong>Inherited and undeclared.</strong> Removes the create-from-typed-text entry, keeping the popup form path.(default: false) |
no_create_edit | boolean | <strong>Inherited and undeclared.</strong> Removes the create-and-edit popup, keeping the create-from-text entry.(default: false) |
search_threshold | number | <strong>Inherited and undeclared.</strong> Minimum number of typed characters before the record search runs. Without it, the search fires on focus. |
create_name_field | field | <strong>Inherited and undeclared on the many2one widget too.</strong> Field the typed text is written into when quick-creating. |
can_scan_barcode | boolean | <strong>Inherited and undeclared on the many2one widget too.</strong> Enables the barcode scan affordance on the autocomplete.(default: false) |
hide_model and model_field overlap. The source comment spells out the intent: the model dropdown is shown in exactly one case, when neither option is set. Setting model_field alone already hides the selector, so adding hide_model on top of it changes nothing. And when model_field points at something that is not a many2one to ir.model, the widget throws an explicit error rather than failing quietly.
Working examples
Seven options it accepts and never declares
Version compatibility
| Version | Status | Notes |
|---|---|---|
| Odoo 20.0 | In development | Not released. Options unchanged; the development branch adds a sync fix for the model selector. See below. |
| Odoo 19.0 | Verified | Verified against the shipped source. Rebuilt on the shared Many2One component; relational values became objects instead of tuples. |
| Odoo 18.0 | Verified | Same two options and same behavior. Rendered through the Many2OneField component. |
| Odoo 17.0 | Verified | Same two options. This is the version that introduced the descriptor and the declared option list. |
| Odoo 16.0 | Verified | Both options work but neither is declared; the component was registered directly and the prop was called hideModelSelector. |
Upgrade note. The two options and the two supported field types have been stable since Odoo 16, so view XML carries over unchanged. What moved is the internals: Odoo 16 registered the component class directly and named its prop hideModelSelector; Odoo 17 introduced the descriptor with the declared options; Odoo 19 rebuilt the render path on the shared Many2One component and switched relational values from tuples to objects. Custom JavaScript that patched this widget on 16, 17 or 18 needs rewriting for 19; XML does not.
What is changing in Odoo 20
Common problems and fixes
| Symptom | Cause and fix |
|---|---|
| The model dropdown will not disappear | Neither hide_model nor model_field is set. The source shows the selector renders in exactly that one case. Set one of the two options. Setting both is harmless but adds nothing. |
| Error about model_field not being a many2one to ir.model | The named field is a char, a selection, or a many2one to another model. Point model_field at a real many2one('ir.model') field, which is what automation-style models use. |
| The reference empties itself when I change the model | Intended behavior. Changing the model field clears the reference so it cannot point at a record of the wrong model. Pick the model first, then the record. If users need both preserved, split them into two fields. |
| The referenced record shows an old name | In char mode the display name is fetched once and cached per raw value for the session. Reload the page. If names change often, store a real reference field instead of a char. |
| no_create is ignored | Usually a typo in the options dictionary, since the option itself is honored but never declared, so nothing validates it. Check spelling carefully. Undeclared options fail silently by design. |
| The record autocomplete stays empty | No model is selected yet; the autocomplete only renders once a relation is known. Choose a model, or supply one through model_field or a default value. |
| The field will not save on a char column | The stored string does not match the model,id shape the widget parses. Store values as res.partner,42 with no spaces, or convert the column to a real reference field. |
Reference field vs the alternatives
| Widget | Best for | Key difference |
|---|---|---|
reference | Fields whose target model genuinely varies from record to record | Stores model and id together and renders a model selector next to the record autocomplete |
| many2one | A relation with one known target model | Database-level foreign key, far easier to filter, group and report on |
| selection | Choosing the model only, with no record behind it | Plain value list, no record lookup and no relation |
char | Storing a raw model,id string without any picker | No model dropdown, no autocomplete, no display name resolution |
Frequently asked questions
What is the difference between a reference field and a many2one?+
How do I hide the model dropdown?+
Can I use the reference widget on a char field?+
Do many2one options like no_create work on a reference field?+
Why does my reference clear itself?+
Modelling something that points at more than one thing?
Reference fields are usually a sign of a data model decision worth getting right the first time: one flexible column, or a few explicit ones plus reporting that actually works. We do that modelling work as part of Odoo customization on 16 through 19, before it becomes a migration problem.
Book a free consultation