Skip to content

Odoo XML IDs (External IDs): The Developer's Guide

DeployMonkey Team · March 22, 2026 10 min read

What Is an XML ID?

An XML ID (also called External ID or XMLID) is a unique string identifier that maps to a database record. Instead of referencing records by their integer ID (which varies between databases), you use a stable string like base.main_company or sale.model_sale_order.

Format

# Format: module_name.record_id
# Examples:
base.main_company          # The main company
base.user_admin            # The admin user
sale.model_sale_order      # The sale.order model record
account.account_invoices   # The invoice report action
hr.department_management   # The Management department

How XML IDs Are Created

In XML Data Files

<!-- The 'id' attribute becomes the XML ID -->
<record id="my_menu" model="ir.ui.menu">
    <field name="name">My Menu</field>
</record>
<!-- XML ID: my_module.my_menu -->

<!-- For views -->
<record id="view_partner_form" model="ir.ui.view">
    <field name="name">partner.form</field>
    <field name="model">res.partner</field>
    <field name="arch" type="xml">
        <form>...</form>
    </field>
</record>
<!-- XML ID: my_module.view_partner_form -->

In Python

# Create a record with an XML ID
self.env['ir.model.data'].create({
    'name': 'my_record',
    'module': 'my_module',
    'model': 'res.partner',
    'res_id': partner.id,
})
# XML ID: my_module.my_record

Referencing XML IDs

In XML

<!-- ref attribute (Most common) -->
<field name="parent_id" ref="base.main_company"/>

<!-- eval with ref() function -->
<field name="group_ids" eval="[(4, ref('base.group_user'))]"/>

<!-- In domains -->
<field name="domain">[('company_id', '=', ref('base.main_company'))]</field>

In Python

# self.env.ref() — the most common way
company = self.env.ref('base.main_company')
print(company.name)  # "My Company"

# With raise_if_not_found=False (won't crash if missing)
record = self.env.ref('my_module.my_record', raise_if_not_found=False)
if record:
    # record exists
    pass

# Get the XML ID of a record
xmlid = record.get_external_id()
# Returns: {42: 'my_module.my_record'}

Where XML IDs Are Stored

# In the ir_model_data table
SELECT module, name, model, res_id
FROM ir_model_data
WHERE module = 'sale' AND name = 'model_sale_order';

# Result:
# module | name             | model        | res_id
# sale   | model_sale_order | ir.model     | 42

Common XML ID Patterns

PatternExamplePurpose
model_*sale.model_sale_orderReference to ir.model record
field_*sale.field_sale_order__nameReference to ir.model.fields
view_*sale.view_order_formView definitions
action_*sale.action_quotationsWindow actions
group_*sales_team.group_sale_managerSecurity groups
access_*sale.access_sale_orderAccess rules
rule_*sale.sale_order_ruleRecord rules
menu_*sale.menu_sale_rootMenu items

Finding XML IDs

In the UI (Developer Mode)

  1. Enable Developer Mode: Settings → Activate Developer Mode
  2. Hover over any field → shows technical info including XML ID
  3. Or: Debug menu → View Metadata → shows External ID

In the Database

# Find XML ID for a specific record
SELECT module, name FROM ir_model_data
WHERE model = 'res.partner' AND res_id = 1;

# Find all XML IDs for a module
SELECT name, model, res_id FROM ir_model_data
WHERE module = 'sale'
ORDER BY model, name;

Common Mistakes

  • Hardcoding database IDs — Use self.env.ref('module.xmlid') instead of self.env['model'].browse(42)
  • Forgetting module prefixref('my_record') won't work, use ref('my_module.my_record')
  • Duplicate XML IDs — Two records with the same id in the same module causes update conflicts
  • Referencing non-existent XML IDs — Crashes on module install. Use raise_if_not_found=False for optional references

AI + XML IDs

Claude Code knows all standard Odoo XML IDs. Ask it: "What's the XML ID for the Sales Manager group?" or "How do I reference the invoice report action?" — it returns the correct XML ID instantly without you having to search the source code.