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 departmentHow 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_recordReferencing 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 | 42Common XML ID Patterns
| Pattern | Example | Purpose |
|---|---|---|
model_* | sale.model_sale_order | Reference to ir.model record |
field_* | sale.field_sale_order__name | Reference to ir.model.fields |
view_* | sale.view_order_form | View definitions |
action_* | sale.action_quotations | Window actions |
group_* | sales_team.group_sale_manager | Security groups |
access_* | sale.access_sale_order | Access rules |
rule_* | sale.sale_order_rule | Record rules |
menu_* | sale.menu_sale_root | Menu items |
Finding XML IDs
In the UI (Developer Mode)
- Enable Developer Mode: Settings → Activate Developer Mode
- Hover over any field → shows technical info including XML ID
- 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 ofself.env['model'].browse(42) - Forgetting module prefix —
ref('my_record')won't work, useref('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=Falsefor 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.