Actions
Window Actions
Basic Window Action
xml
<record id="action_model_list" model="ir.actions.act_window">
<field name="name">Model Records</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="target">current</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first record!
</p>
</field>
</record>
Window Action with Domain and Context
xml
<record id="action_filtered_records" model="ir.actions.act_window">
<field name="name">Active Records</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('active', '=', True)]</field>
<field name="context">{
'default_active': True,
'search_default_current_month': 1
}</field>
<field name="limit">80</field>
</record>
Form Action for Specific Record
xml
<record id="action_open_record" model="ir.actions.act_window">
<field name="name">Edit Record</field>
<field name="res_model">model.name</field>
<field name="view_mode">form</field>
<field name="res_id" ref="model_record_id"/>
<field name="target">new</field>
</record>
Multi-View Window Action
xml
<record id="action_multi_view" model="ir.actions.act_window">
<field name="name">Multi View Action</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form,kanban,calendar,graph,pivot</field>
<field name="view_id" ref="view_tree_custom"/>
</record>
<!-- Specify view sequences -->
<record id="action_multi_view_view_tree" model="ir.actions.act_window.view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_tree_custom"/>
<field name="act_window_id" ref="action_multi_view"/>
</record>
<record id="action_multi_view_view_form" model="ir.actions.act_window.view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="view_form_custom"/>
<field name="act_window_id" ref="action_multi_view"/>
</record>
Server Actions
Python Code Server Action
xml
<record id="server_action_python" model="ir.actions.server">
<field name="name">Process Records</field>
<field name="model_id" ref="model_model_name"/>
<field name="binding_model_id" ref="model_model_name"/>
<field name="state">code</field>
<field name="code">
for record in records:
if record.state == 'draft':
record.write({
'state': 'confirmed',
'confirmed_date': fields.Datetime.now(),
'confirmed_by': env.user.id
})
# Send notification
env['mail.thread'].message_post(
body="Records have been processed",
message_type='notification'
)
# Log activity
records.message_post(body="Status updated to confirmed")
</field>
</record>
Multi-Action Server Action
xml
<record id="server_action_multi" model="ir.actions.server">
<field name="name">Multi Step Process</field>
<field name="model_id" ref="model_model_name"/>
<field name="state">multi</field>
</record>
<record id="server_action_step1" model="ir.actions.server">
<field name="name">Step 1: Validate</field>
<field name="model_id" ref="model_model_name"/>
<field name="state">code</field>
<field name="sequence">1</field>
<field name="code">
if not records.filtered(lambda r: r.state == 'draft'):
raise UserError("No draft records to process")
</field>
</record>
<record id="server_action_step2" model="ir.actions.server">
<field name="name">Step 2: Update Records</field>
<field name="model_id" ref="model_model_name"/>
<field name="state">code</field>
<field name="sequence">2</field>
<field name="code">
records.write({'state': 'processing'})
</field>
</record>
Object Method Server Action
xml
<record id="server_action_method" model="ir.actions.server">
<field name="name">Call Method</field>
<field name="model_id" ref="model_model_name"/>
<field name="binding_model_id" ref="model_model_name"/>
<field name="state">object_create</field>
<field name="crud_model_id" ref="model_other_model"/>
<field name="link_field_id" ref="field_model_name_other_id"/>
<field name="fields_lines">
<record model="ir.server.object.lines">
<field name="col1" ref="field_other_model_name"/>
<field name="value">record.name + ' - Copy'</field>
<field name="type">equation</field>
</record>
<record model="ir.server.object.lines">
<field name="col1" ref="field_other_model_date"/>
<field name="value">datetime.now()</field>
<field name="type">equation</field>
</record>
</field>
</record>
URL Actions
External URL Action
xml
<record id="action_external_url" model="ir.actions.act_url">
<field name="name">Open Website</field>
<field name="url">https://www.example.com</field>
<field name="target">new</field>
</record>
Dynamic URL Action
xml
<record id="action_dynamic_url" model="ir.actions.act_url">
<field name="name">Open Record URL</field>
<field name="url">/web#id={{object.id}}&model={{object._name}}&view_type=form</field>
<field name="target">self</field>
</record>
Report URL Action
xml
<record id="action_report_url" model="ir.actions.act_url">
<field name="name">Download Report</field>
<field name="url">/report/pdf/module.report_template/{{object.id}}</field>
<field name="target">self</field>
</record>
Report Actions
PDF Report Action
xml
<record id="action_report_pdf" model="ir.actions.report">
<field name="name">Model Report</field>
<field name="model">model.name</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">module.report_template</field>
<field name="report_file">module.report_template</field>
<field name="binding_model_id" ref="model_model_name"/>
<field name="binding_type">report</field>
</record>
HTML Report Action
xml
<record id="action_report_html" model="ir.actions.report">
<field name="name">HTML Report</field>
<field name="model">model.name</field>
<field name="report_type">qweb-html</field>
<field name="report_name">module.report_template_html</field>
<field name="report_file">module.report_template_html</field>
<field name="paperformat_id" ref="base.paperformat_euro"/>
</record>
Excel Report Action
xml
<record id="action_report_xlsx" model="ir.actions.report">
<field name="name">Excel Export</field>
<field name="model">model.name</field>
<field name="report_type">xlsx</field>
<field name="report_name">module.report_excel</field>
<field name="report_file">module.report_excel</field>
<field name="binding_model_id" ref="model_model_name"/>
</record>
Wizard Actions
Simple Wizard Action
xml
<record id="action_wizard_simple" model="ir.actions.act_window">
<field name="name">Simple Wizard</field>
<field name="res_model">wizard.model</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="binding_model_id" ref="model_model_name"/>
<field name="binding_type">action</field>
</record>
Multi-Step Wizard Action
xml
<record id="action_wizard_multi_step" model="ir.actions.act_window">
<field name="name">Multi Step Wizard</field>
<field name="res_model">wizard.multi.step</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="context">{
'default_step': 'step1',
'active_ids': active_ids,
'active_model': active_model
}</field>
</record>
Wizard with Custom View
xml
<record id="wizard_view_form" model="ir.ui.view">
<field name="name">wizard.form</field>
<field name="model">wizard.model</field>
<field name="arch" type="xml">
<form string="Wizard Title">
<group>
<field name="field1"/>
<field name="field2"/>
</group>
<footer>
<button string="Process" name="action_process"
type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary"
special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_wizard_custom_view" model="ir.actions.act_window">
<field name="name">Custom Wizard</field>
<field name="res_model">wizard.model</field>
<field name="view_mode">form</field>
<field name="view_id" ref="wizard_view_form"/>
<field name="target">new</field>
</record>
Client Actions
JavaScript Client Action
xml
<record id="action_client_js" model="ir.actions.client">
<field name="name">Custom Dashboard</field>
<field name="tag">custom_dashboard</field>
<field name="context">{
'dashboard_type': 'sales',
'period': 'monthly'
}</field>
</record>
Client Action with Parameters
xml
<record id="action_client_params" model="ir.actions.client">
<field name="name">Interactive Chart</field>
<field name="tag">interactive_chart</field>
<field name="params" eval="{'chart_type': 'line', 'data_source': 'sales.report'}"/>
<field name="context">{'default_period': 'current_year'}</field>
</record>
Cron Actions
Scheduled Action
xml
<record id="cron_daily_cleanup" model="ir.cron">
<field name="name">Daily Cleanup</field>
<field name="model_id" ref="model_model_name"/>
<field name="state">code</field>
<field name="code">model.cleanup_old_records()</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="nextcall" eval="(DateTime.now() + timedelta(days=1)).strftime('%Y-%m-%d 02:00:00')"/>
<field name="active" eval="True"/>
</record>
Cron with Method Call
xml
<record id="cron_send_reminders" model="ir.cron">
<field name="name">Send Daily Reminders</field>
<field name="model_id" ref="model_model_name"/>
<field name="state">object_write</field>
<field name="code">send_daily_reminders()</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="nextcall" eval="(DateTime.now() + timedelta(hours=1)).strftime('%Y-%m-%d %H:00:00')"/>
<field name="user_id" ref="base.user_admin"/>
<field name="doall" eval="False"/>
</record>
Action Bindings
Model Binding
xml
<record id="action_with_binding" model="ir.actions.server">
<field name="name">Quick Action</field>
<field name="model_id" ref="model_model_name"/>
<field name="binding_model_id" ref="model_model_name"/>
<field name="binding_type">action</field>
<field name="state">code</field>
<field name="code">
records.write({'processed': True})
</field>
</record>
Report Binding
xml
<record id="report_with_binding" model="ir.actions.report">
<field name="name">Custom Report</field>
<field name="model">model.name</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">module.report_template</field>
<field name="binding_model_id" ref="model_model_name"/>
<field name="binding_type">report</field>
</record>
View Binding (Button)
xml
<!-- In view definition -->
<button name="%(action_custom_wizard)d"
string="Open Wizard"
type="action"
class="btn-primary"/>
<button name="action_server_method"
string="Server Action"
type="object"
confirm="Are you sure?"/>
Advanced Action Patterns
Conditional Actions
xml
<record id="action_conditional" model="ir.actions.act_window">
<field name="name">Conditional View</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('state', 'in', ['draft', 'confirmed'])]</field>
<field name="context">{
'create': False if context.get('readonly_mode') else True,
'edit': False if context.get('readonly_mode') else True,
'delete': False
}</field>
</record>
Action with Groups
xml
<record id="action_restricted" model="ir.actions.act_window">
<field name="name">Admin Only Action</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="groups_id" eval="[(4, ref('base.group_system'))]"/>
</record>
Parent-Child Actions
xml
<record id="action_parent_records" model="ir.actions.act_window">
<field name="name">Parent Records</field>
<field name="res_model">parent.model</field>
<field name="view_mode">tree,form</field>
</record>
<record id="action_child_records" model="ir.actions.act_window">
<field name="name">Child Records</field>
<field name="res_model">child.model</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('parent_id', '=', active_id)]</field>
<field name="context">{
'default_parent_id': active_id,
'search_default_parent_id': active_id
}</field>
</record>
Menu Integration
Top Menu
xml
<menuitem id="menu_main"
name="Main Module"
sequence="10"/>
Sub Menu with Action
xml
<menuitem id="menu_records"
name="Records"
parent="menu_main"
action="action_model_list"
sequence="10"/>
Menu with Groups
xml
<menuitem id="menu_admin"
name="Administration"
parent="menu_main"
action="action_admin_panel"
groups="base.group_system"
sequence="100"/>
Dynamic Menu
xml
<menuitem id="menu_dynamic"
name="Dynamic Menu"
parent="menu_main"
action="action_dynamic_content"
active="True"
sequence="20"/>
Security and Permissions
Action with Record Rules
xml
<record id="action_with_rules" model="ir.actions.act_window">
<field name="name">My Records</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('user_id', '=', uid)]</field>
</record>
<!-- Corresponding record rule -->
<record id="rule_own_records" model="ir.rule">
<field name="name">Own Records Only</field>
<field name="model_id" ref="model_model_name"/>
<field name="domain_force">[('user_id', '=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
Action Security
xml
<record id="action_secure" model="ir.actions.act_window">
<field name="name">Secure Action</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="groups_id" eval="[(6, 0, [ref('base.group_user'), ref('custom.group_manager')])]"/>
</record>
Action Context Variables
Common Context Variables
xml
<record id="action_with_context" model="ir.actions.act_window">
<field name="name">Context Example</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="context">{
'default_field_name': 'Default Value',
'search_default_filter_name': 1,
'group_by': 'category_id',
'create': True,
'edit': True,
'delete': False,
'duplicate': False,
'active_test': False,
'lang': 'en_US',
'tz': 'UTC',
'uid': uid,
'company_id': company_id,
'allowed_company_ids': [company_id]
}</field>
</record>
Dynamic Context
xml
<record id="action_dynamic_context" model="ir.actions.act_window">
<field name="name">Dynamic Context</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="context">{
'default_date': context_today().strftime('%Y-%m-%d'),
'default_user_id': uid,
'search_default_my_records': 1 if context.get('filter_my_records') else 0,
'tree_view_ref': 'module.view_tree_compact' if context.get('compact_view') else False
}</field>
</record>
Performance Optimization
Optimized Actions
xml
<record id="action_optimized" model="ir.actions.act_window">
<field name="name">Optimized List</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="limit">80</field>
<field name="context">{
'active_test': True,
'prefetch_fields': ['name', 'state', 'date']
}</field>
<field name="domain">[('active', '=', True)]</field>
</record>
Lazy Loading Actions
xml
<record id="action_lazy_load" model="ir.actions.act_window">
<field name="name">Lazy Loaded Records</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
<field name="auto_search" eval="False"/>
<field name="context">{'search_disable_custom_filters': True}</field>
</record>