project
On an Odoo task form the project field is not a plain dropdown: the project widget wraps the standard many2one and shows a gray Private placeholder when the task belongs to nobody's project. Small widget, one hardcoded assumption worth knowing.
| Technical name | project |
|---|---|
| Field types | many2one |
| Views | form, list |
| Module | project |
| Used in core | 5 occurrences across 1 module: project (task form and task list views) |
| Versions | Odoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0 |
| No-code setup | No. Studio offers the generic Many2one; this project variant is applied in XML. |
| Alternatives | many2one, res_partner_many2one, so_line_field |
What the Project field widget does
What this means for your team
Supported options in Odoo 19
| Option | Type | What it does |
|---|---|---|
no_open | boolean | Inherited from many2one. Removes the internal link so clicking the value in readonly does not open the project form. Odoo core uses it on the task list view of this very widget.(default: false) |
no_create | boolean | Inherited from many2one. Hides both quick create and Create and Edit in the autocomplete, so users can only pick existing projects.(default: false) |
no_quick_create | boolean | Inherited from many2one. Hides only the inline Create "x" entry; Create and Edit stays available.(default: false) |
no_create_edit | boolean | Inherited from many2one. Hides the Create and Edit dialog entry; quick create stays available.(default: false) |
search_threshold | integer | Inherited from many2one, new in 19. The dropdown only starts searching once the user has typed this many characters, useful on databases with thousands of projects.(since Odoo 19.0) |
placeholder_field | field name | Inherited from many2one, new in 19. Reads the placeholder text from another field on the record. The widget's own Private placeholder takes over when project_id is empty and not required.(since Odoo 19.0) |
can_scan_barcode | boolean | Undocumented, inherited from many2one: read in extractM2OFieldProps but never declared. Enables barcode based selection on mobile.(default: false) |
create_name_field | field name | Undocumented, inherited from many2one: read in extractM2OFieldProps but never declared. Sets which field receives the typed text when quick creating a record. |
All options below are inherited from the standard many2one. The two marked undocumented are read in extractM2OFieldProps but never declared in supportedOptions, so no Studio UI will ever show them.
Working examples
From display_in_project to Private: the widget's history
Version compatibility
| Version | Status | Notes |
|---|---|---|
| Odoo 20.0 | In development | Not released. Adds template task awareness (All Projects placeholder) in the development branch; see below. |
| Odoo 19.0 | Verified | Verified against the shipped source and tested on a clean database. |
| Odoo 18.0 | Verified | Same Private placeholder logic; older subclass based implementation. |
| Odoo 17.0 | Partial / changed | Widget exists but with different logic: parent_id check, display_in_project auto write, hidden display names. |
| Odoo 16.0 | Not available | The widget does not exist in 16.0; task views use the plain many2one. |
No XML changes are needed between 17, 18 and 19. If you relied on the 17 behavior of auto setting display_in_project, that write disappeared in 18 and needs an explicit onchange or automation instead.
What is changing in Odoo 20
Common problems and fixes
| Symptom | Cause and fix |
|---|---|
| The Private placeholder never shows | The field is required in this view; the widget only shows Private when project_id may stay empty. Check the required attribute or expression on the field in the current view. |
| Widget applied to another many2one shows odd placeholder behavior | The source reads record.data.project_id by literal name, regardless of which field carries the widget. Only use widget="project" on fields named project_id; fork the widget for other fields. |
| After migrating from 17, display_in_project no longer updates on project change | The 17 widget auto set display_in_project to true; 18 removed that write. Add an onchange or automation rule if your customization depended on it. |
| The picker searches on the first keystroke and feels slow | No typeahead threshold is set; the widget queries immediately like any many2one. On Odoo 19, add options="{'search_threshold': 3}". |
Project field widget vs the alternatives
| Widget | Best for | Key difference |
|---|---|---|
project | The project field on tasks, with a clear Private empty state | Standard many2one plus a Private placeholder tied to the project_id field name |
| many2one | Any relational field without task privacy semantics | No Private placeholder, no forced full width |
| res_partner_many2one | Partner fields with company autocomplete | Adds IAP powered company suggestions instead of an empty state label |
| so_line_field | Sale order line links on timesheets | Flags edited lines through an is_so_line_edited companion field |
Frequently asked questions
What does the project widget do in Odoo?+
Why does my task's project field say Private?+
Can I use the project widget on my own many2one field?+
Does the project widget support standard many2one options?+
What changes for this widget in Odoo 20?+
Tasks, projects and privacy rules that behave
Private tasks, template tasks, portal visibility: Odoo project setups fail in the details. We configure and extend Odoo project for teams from 5 to 500 users, including custom pickers and automations around project_id.
Plan my Odoo project setup