Skip to main content
iVentureTeam

many2one

The autocomplete dropdown on Customer, Product and every other record link in Odoo is the many2one widget. It is the default for its field type, which is why you rarely type its name, and why its options are worth knowing by heart.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 19, 2026Updated August 19, 20267 min read
Odoo 19 form view showing a many2one field with its autocomplete dropdown open, including Search More and Create and edit entries.
Studio nameMany2One
Technical namemany2one
Field typesmany2one
Viewsform, list, kanban
Moduleweb, present in every Odoo database
Used in core6 explicit occurrences across 5 modules, including sale_expense, stock, purchase, event, point_of_sale; applied implicitly to every many2one field in every view
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0
No-code setupYes: it is the default widget for Many2One fields in Studio
Alternativesmany2one_avatar, radio, selection

What the Many2one field does

Pick any Odoo form: the Customer on a sales order, the Product on an order line, the Responsible on a task. Each of those inputs is the many2one widget: a text box that searches another model as you type, shows matches in a dropdown, and stores a link to the record you pick.

The dropdown carries more than search results. Depending on your access rights and the widget's options it appends Search More... (a full search dialog), Create "..." (quick create from the typed text) and Create and edit... (a popup form). Once a record is selected, an internal link button opens it, and the link resolves to /odoo/<model>/<id>, so middle-click and open-in-new-tab work like on any web link.

Because it is the registered default for the many2one field type, you almost never write widget="many2one" in XML. Core itself does so only 6 times. You interact with this widget through its options instead, and those options are inherited by a whole family of derived widgets, from many2one_avatar to stock.forced_placeholder, all built on the same buildM2OFieldDescription helper in the source.

What this means for your team

Relational fields are where data quality is won or lost. The two decisions this widget lets you make per view are deceptively important.

Who is allowed to create records from here? Quick create is fast, and fast is how you end up with three versions of the same customer, one per typo. Setting no_quick_create on customer-facing forms while leaving full create available forces new records through the complete form, where required fields and duplicate warnings live. Setting no_create outright is the right call for controlled masters such as tax grids or warehouses.

How does search behave on large tables? By default the dropdown fires a search on focus, before a single character is typed. On a model with a million partners that is a wasted query per click. The Odoo 19 search_threshold option delays the search until the user has typed a minimum number of characters, which is measurably kinder to both the database and the user reading the results.

Setting it up in Odoo Studio (no code)

In Studio the widget comes with the field type, and its most useful options are exposed as checkboxes.

  1. Open the view in Studio and drag a Many2One field from the New Fields section, or select an existing many2one field.

  2. In the Properties tab, pick the related model when prompted.

  3. Tick Disable creation to remove the create entries from the dropdown, and Disable opening to remove the link that opens the record.

  4. Set Typeahead search to a number of characters to delay the search on large models.

  5. Click Domain to filter which records can be selected.

What Studio cannot do here

Studio's checkboxes cover no_create, no_open, the domain and the search threshold. The finer-grained create controls, allowing quick create but not the popup form or the reverse, are the no_quick_create and no_create_edit options, XML only.

The two undocumented options are also XML only: can_scan_barcode, which adds a barcode scan button on mobile, and create_name_field, which tells quick create which field of the target model receives the typed text when it is not called name.

Supported options in Odoo 19

Verified against many2one_field.js in the Odoo 19.0 web module. The first six options are declared in supportedOptions; the last two are read only in extractProps and appear in no options panel, which is exactly the kind of gap between declaration and behavior this page exists to document.

OptionTypeWhat it does
no_openbooleanRemoves the internal link that opens the selected record, so the value is select-only. Studio exposes this as Disable opening.
no_createbooleanRemoves every create path from the dropdown: both quick create and the Create and edit popup. Overrides the two finer options below. Studio exposes this as Disable creation.
no_quick_createbooleanRemoves only the inline Create "..." entry that creates a record from the typed text. The Create and edit popup form remains available.
no_create_editbooleanRemoves only the Create and edit popup form. One-click quick create from the typed text remains available.
search_thresholdnumberMinimum number of typed characters before the autocomplete queries the server. Unset, the search fires on focus, before any typing. Studio exposes this as Typeahead search.(since Odoo 19.0)
placeholder_fieldfield name (char)A char field on the current record whose value becomes the input's placeholder text, making the hint dynamic per record.(since Odoo 19.0)
can_scan_barcodeboolean (undocumented)Read only in extractProps, declared nowhere. On mobile devices with a supported camera it adds a barcode scan button; a scan that matches exactly one record selects it directly.
create_name_fieldfield name (undocumented)Read only in extractProps, declared nowhere. Tells quick create which field on the target model receives the typed text, for models whose display field is not called name.(default: name)

The create options stack, they do not compete. no_create wins over everything and kills both create paths. With create allowed, no_quick_create removes only the inline Create "..." entry and no_create_edit removes only the Create and edit... popup. Separately, the can_create and can_write attributes (Python expressions on the field element) gate the same behavior from the access-rights side; no_create and a false can_create produce the same end state.

Working examples

Lock down a controlled master

<field name="warehouse_id" options="{'no_create': True, 'no_open': True}"/>

No create entries, no link out of the form. The user can only pick from existing warehouses.

Allow full create, block one-click quick create

<field name="partner_id" options="{'no_quick_create': True}"/>

New customers must go through the Create and edit popup form, where your required fields apply.

Delay search on a huge model

<field name="partner_id" options="{'search_threshold': 3}"/>

No query fires until the user has typed 3 characters. New in Odoo 19.

Quick create into a model whose name field is not name

<field name="employee_id" options="{'create_name_field': 'legal_name'}"/>

The typed text lands in legal_name instead of name when the record is created.

Inside the Odoo 19 rewrite

Odoo 19 rebuilt this widget around a standalone Many2One component plus a computeM2OProps helper, and that refactor explains several behaviors worth knowing.

Quick create is lazier than it looks. Choosing Create "..." does not call the server. The source's quickCreate merely updates the field with {id: false, display_name: name}; the real name_create happens when the record is saved. Cancel the form and nothing was created.

Multi-line display names are split. If the target model's display_name contains line breaks (partner addresses in some contexts), only the first line renders as the link and the remaining lines render as extra text below it, trimmed line by line.

The barcode path has a limit of 2. With can_scan_barcode on a mobile device, a scan runs a name_search with limit: 2: exactly one match selects it directly, anything else drops the barcode into the input and falls back to the normal search flow.

A record with no display name renders as "Unnamed". That string comes from this widget, not from the ORM.

One dead knob: the component declares a searchLimit prop, but extractProps never fills it from the view, so there is no XML option to change the dropdown's result count on this widget.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. Options unchanged on the development branch; internal props-schema rework. See below.
Odoo 19.0VerifiedVerified against the shipped source. Adds search_threshold and placeholder_field; drops the list./kanban. aliases.
Odoo 18.0Partial / changedFour no_* options only; no search_threshold or placeholder_field. Also registered as list.many2one and kanban.many2one.
Odoo 17.0Partial / changedSame four no_* options as 18.0, verified in the 17.0 source.
Odoo 16.0Partial / changedPresent with the core no_* option set; predates the Odoo 19 component refactor.

Upgrade note. Odoo 18 and earlier registered list.many2one and kanban.many2one as duplicate entries, with a source comment saying they exist "to prevent the fallback on legacy widgets". Odoo 19 removed both aliases along with the legacy machinery. XML is unaffected, but JavaScript that patched those registry entries or imported Many2OneField internals needs review: the interactive logic now lives in the Many2One component, not the field wrapper.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. The notes below are read from the public development branch and are not final until release.

No option changes. The declared options, the two undocumented ones, and the registration are all unchanged on master. The diff is internal: the component migrates to the new props-schema API (useProps with typed validators) and exports a reusable many2OneFieldProps schema. Custom widgets that spread Many2OneField.props the old way will need the new import, and the stock.forced_placeholder source on master already shows the conversion pattern.

We re-verify this page against the shipped release before updating the table.

Common problems and fixes

SymptomCause and fix
Users keep creating duplicate records from the dropdownQuick create accepts any typed text with one click, bypassing your form's required fields. Set options="{'no_quick_create': True}" to force creation through the popup form, or no_create to block creation entirely.
The dropdown search feels slow on a big modelBy default the search fires on focus, before the user types anything. Set options="{'search_threshold': 2}" (Odoo 19+) so the query waits for typed characters.
Quick create fails with a required-field errorThe target model has required fields beyond its name, so name_create cannot save it at save time. Use no_quick_create so users go through Create and edit, where all required fields can be filled.
The value shows as "Unnamed"The linked record has no display_name; the widget substitutes the Unnamed label itself. Fix the target record's name field, or check _compute_display_name on the target model.
The record link is missingno_open is set on the field, or the record is not saved yet and the input is in its floating state. Remove no_open from the options if users should navigate to the record.
A JavaScript patch broke after upgrading to Odoo 19The widget was rebuilt around the Many2One component; list.many2one and kanban.many2one registry aliases were removed. Re-target the patch at the Many2One component or computeM2OProps, and drop references to the removed aliases.

Many2one field vs the alternatives

WidgetBest forKey difference
many2oneAny single-record link where users search by nameThe default: autocomplete plus create and open controls, all governed by options
many2one_avatarLinks to people, users or employeesSame behavior plus the record's avatar image next to the name
radioSmall, stable sets of records (under a dozen)Shows every option at once as radio buttons; no search, no create
selectionRead-mostly picks from a short listRenders the many2one as a plain dropdown with one cached search, capped at 100 records

The rule of thumb: many2one for the general case, a derived widget when the target model deserves special rendering (avatars for people, badges for read-only states), and radio or selection when the option list is short enough that a dropdown search is overkill.

Frequently asked questions

How do I disable record creation in an Odoo many2one field?+
Set options="{'no_create': True}" on the field, or tick Disable creation in Studio. To remove only the one-click path but keep the popup form, use no_quick_create instead.
Why don't I see widget="many2one" in Odoo's own views?+
Because it is the registered default for the many2one field type; every many2one field without an explicit widget already uses it. Core spells it out only 6 times, usually to force it where another default would apply.
How do I limit which records can be selected?+
That is the domain attribute on the field, not a widget option: domain="[('is_company', '=', True)]". The widget applies it to the autocomplete, the Search More dialog, and barcode scans alike.
What does search_threshold do?+
New in Odoo 19, it sets the minimum number of typed characters before the autocomplete queries the server. Without it the search runs as soon as the field gains focus. Studio calls it Typeahead search.
Does quick create save the record immediately?+
No. Picking Create "..." only stores the typed name in the field with a pending id; the actual record is created when you save the form. Discard the form and no record is created.
Can users scan a barcode to fill a many2one?+
Yes, with the undocumented can_scan_barcode option on a mobile device. The scan runs a name_search limited to 2 results; a unique match is selected directly, otherwise the barcode text lands in the search input.

Duplicate customers and messy master data?

Nine times out of ten the fix starts with how your many2one fields are configured: who may create records, from where, and behind which required fields. We audit and tighten relational fields across your Odoo views, from quick wins like no_quick_create to full deduplication runs.

Clean up our record links

How this page was produced

The option table was read from many2one_field.js and many2one.js in the Odoo 19.0 web module, including the extractProps path that reveals can_scan_barcode and create_name_field, and the quick-create and barcode code paths described above. Version differences were confirmed by diffing the same file on the 16.0, 17.0 and 18.0 branches, and the Odoo 20 section against the public development branch, which is marked as unreleased. Spotted an error or a version difference? Tell us and we will correct the page.