Skip to main content
iVentureTeam

activity_model_selector

Choose a model, then choose a record: the two-step picker on the Schedule Activity wizard. Its cleverest part is protecting the summary you already typed from being wiped by the model change.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 27, 2026Updated September 1, 20266 min read
Technical nameactivity_model_selector
Field typeschar
Viewsform
Modulemail, the Discuss module
Used in core1 occurrence, the Schedule Activity wizard in mail
VersionsOdoo 20.0, Odoo 19.0
No-code setupNo. It depends on a server method and on companion fields of the wizard
Alternativesreference, many2one, selection, list_activity

What the activity model selector does

Most activities are scheduled from the record they concern, so the link is implicit. Scheduling from the activity wizard is different: nothing says what the activity is about, and the answer could be any record in the database.

This widget asks that in two steps. First a model, chosen from a list the server says the user is allowed to link to. Then a record, chosen through a full search dialog opened on that model. Only when both are answered does the wizard get its link.

The reason it is a widget rather than two fields is what happens in between. Changing the model changes which activity types are available, which recomputes several fields on the wizard, including the summary the user has quite likely already typed. The widget carries that text across the change.

What this means for your team

Losing typed text is the fastest way to make a wizard feel broken, and this one is unusually exposed to it because the natural order of filling it in, summary first and link second, is exactly the order that triggers the loss. The source comment says so outright, which is a good sign that it was found the hard way.

The two-step shape is also worth recognizing as a pattern. Any time a record reference can point anywhere, the interface has to narrow the model before the record, and doing it in local state rather than on the record means a half-finished choice never gets saved. If you build something similar, that separation is the part to copy.

Supported options in Odoo 19

There is nothing to configure. The registration provides a component and nothing else: no options, no supported types, no extractor. What it reads and writes are companion fields on the wizard, listed below. Read from activity_model_selector.js, Odoo 19.0.

OptionTypeWhat it does
res_modelcompanion fieldWritten by literal name once a record has been chosen. Never written for a model choice alone.(since Odoo 19.0)
res_model_namecompanion fieldRead by literal name to seed the label shown before anything is chosen.(since Odoo 19.0)
res_idscompanion fieldWritten by literal name with the chosen record. Its absence on dialog close triggers a full reset.(since Odoo 19.0)
summarycompanion fieldSaved before the model change and written back afterwards, so a typed summary survives the recomputation of activity types.(since Odoo 19.0)
notecompanion fieldPreserved the same way as the summary.(since Odoo 19.0)

Four fields are read or written by literal name. The model and its label, the record ids, and the summary and notes that are preserved across the change. All of them belong to the activity wizard, which is why the widget is not portable to another model without matching those names.

Working examples

The core usage

<field name="res_model"
       widget="activity_model_selector"
       string="Link to"/>

One field element covers both steps. The record ids are written by the widget rather than by a second field.

The companion fields it touches

res_model        # written when a record is chosen
res_model_name   # read for the initial label
res_ids          # written with the chosen record
summary, note    # saved and restored across the change

All read by literal name, so the wizard model has to carry them.

Where the model list comes from

# server method, called once per session
mail.activity.schedule.get_model_options()

The result is memoized, so opening the wizard repeatedly does not re-query.

Saving your summary across a recompute

The preservation trick is the part worth reading closely. When a record is chosen, the widget first copies the current summary and notes into a local object. It then updates the model and the record ids without saving, which is what triggers the recomputation of activity types and everything downstream of them. Finally it writes the saved summary and notes back, overwriting whatever the recompute produced.

The same dance happens on reset. Clearing the link recomputes the same fields, so the same save and restore is applied, and then the model selection is cleared through the normal path.

The model list is fetched through a memoized helper, with a comment noting a small hack: the memoization keys on the first argument, so a placeholder is passed first and the actual service second. The practical effect is one server call per session rather than one per wizard.

Local state is used deliberately for the chosen model, with its own comment: writing a model to the record without a record id would leave the wizard in a state the server cannot interpret. So the model lives in the component until a record is picked, and the dialog's close handler resets everything if nothing was chosen.

One consequence of that design is worth knowing: the record label shown after choosing comes from a separate name lookup the widget performs itself, not from the record, so a renamed target will show its old name until the wizard is reopened.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. Behavior identical on the development branch.
Odoo 19.0VerifiedFirst version, with the reworked activity wizard. Verified against the shipped source.
Odoo 18.0Not availableWidget does not exist.
Odoo 17.0Not availableWidget does not exist.
Odoo 16.0Not availableWidget does not exist.

Upgrade note. The widget is new in Odoo 19, with the reworked activity scheduling wizard. There is nothing to migrate from earlier versions, where linking an activity to an arbitrary record was not offered in this form.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. The development branch is unstable and this may still change; we re-verify the page after release.

No behavior change. The two-step flow, the memoized model list, the local state and the summary preservation are all identical. The props and state helpers move to the new syntax, which affects patches rather than views.

Common problems and fixes

SymptomCause and fix
The model list is emptyThe server method returned nothing for this user, usually an access rights matter. Check which models the user may link activities to; the list is server-decided.
My typed summary disappearedSomething bypassed the preservation, for example a customization that changes the model directly. Change the link through the widget, which saves and restores the summary around the recompute.
The wizard is stuck with a model and no recordThe close handler normally resets both when no record was chosen. Reopen the wizard; the model is held in local state and is not saved on its own.
The record label is out of dateIt comes from a name lookup the widget performed when the record was chosen. Reopen the wizard to refresh it.
The model list does not refreshIt is memoized for the session. Reload the page after changing model access.
Options are ignoredThe registration has no extractor. Nothing to configure here.

Activity model selector vs the alternatives

WidgetBest forKey difference
activity_model_selectorLinking an activity to a record on any model, from the scheduling wizardA two-step picker that keeps the model in local state and preserves your summary across the change
referenceA general model plus record picker on any modelStores the pair in one field and needs no companion fields
many2oneA relation whose target model is knownOne step, and enforced at the database level
selectionChoosing a model onlyNo record behind the choice
list_activityShowing the next activity on a rowDisplays activities rather than creating them

Where the target model is known, a plain relation field is simpler and cheaper. Where it varies, the reference widget is the general-purpose two-step picker and does not need companion fields. This one exists because the activity wizard has extra work to do around the change, so use it only there.

Frequently asked questions

Why is it two steps?+
Because an activity can be linked to any model, so the model has to be narrowed before a record can be searched. The model is chosen from a server-provided list, and the record through a full search dialog.
Why does it save my summary?+
Changing the model changes which activity types apply, which recomputes dependent fields including the summary and notes. The widget copies them before the change and writes them back afterwards, and the source comment says exactly that.
Where does the model list come from?+
A server method on the activity wizard, called through a memoized helper so it runs once per session rather than each time the wizard opens.
What happens if I close the record dialog without choosing?+
The widget resets both the model and the record. The model was only ever in local state, so nothing half-made was written to the record.
Can I use it elsewhere?+
Not without matching field names. It reads and writes five companion fields of the activity wizard by literal name. For a general model and record picker, the reference widget is the right choice.

Follow-ups that actually get followed up

Activities, their types and the automation that creates them are the difference between a CRM people work from and one they update afterwards. We configure Odoo activities and automation on versions 16 through 19.

Book a free consultation

How this page was produced

The two-step flow, the memoized model list with its hack comment, the local state comment, the summary and notes preservation and the reset on dialog close were read from activity_model_selector.js on the Odoo 19.0 branch, with the usage taken from mail/wizard/mail_activity_schedule_views.xml. Version coverage comes from the absence of the file on 16.0, 17.0 and 18.0, and a comparison against the public development branch. Spotted an error? Tell us and we will correct the page.