This question has been flagged
1 Reply
29131 Views

I'm currently looking at stored server actions in XML. Here is an example of one, from the crm addon:

        <record id="action_mark_as_lost" model="ir.actions.server">
            <field name="name">Mark As Lost</field>
            <field name="model_id" ref="model_crm_lead"/>
            <field name="state">code</field>
            <field name="code">
                if context.get('active_model') == 'crm.lead' and context.get('active_ids'):
                    self.case_mark_lost(cr, uid, context['active_ids'], context=context)
            </field>
        </record>

What is "model_crm_lead?" Odoo generally refers to models by the name defined in the model, so it's referring to the crm.lead model, shouldn't the tag be:

<field name="model_id" ref="crm.lead"/>

I thought perhaps it is using the class name instead of the internal model name (for some reason), and prefacing it with "model_<MODEL_CLASS_NAME>" but I'm only guessing and don't really know how this field works or where it is explained.

Edit: Is it "model_<MODEL_TABLE_NAME>"? It's that isn't it?

Avatar
Discard
Best Answer

Hello Darrel, before providing an answer, let me put some background information here.

Background:

At loading data by installing resources (models, fields, model-records, views, record rules, actions, menu entries, etc.), Odoo registers mapping records for all resources in the 'ir_model_data' table ('ir.model.data' object), so we can reference those records later, even from other modules.

Mapping records in 'ir_model_data' have the following remarkable columns:

  • module: module name, string literal (not its id)
  • model: fully-qualified dot-separated object name (also known as the object's technical name)
  • res_id: The resource id/Database ID (the PK of the record in the table where the resource is stored)
  • name: record name, a string literal that in conjunction with the module name uniquely identify the record/resource

The record name in conjunction with the module name form what we know as the resource External ID which has the following fully-qualified form: 'module_name.resource_name'.

Records defined in XML data define their External IDs by means of the 'id' attribute of the 'record' tag.

The 'id' attribute can explicitly include 'module_name.' (fully-qualified form) or not. In the later case (relative form) the module that declares the resource is assumed:
* https://github.com/odoo/odoo/blob/8.0/openerp/tools/convert.py#L707

The above long story was required to have enough background for the answer that follows.

Answer:

At processing child 'field' tags of any 'record' tag, the 'ref' attribute is expected to have the External ID of a referenced existing record (fully-qualified or relative form):
* https://github.com/odoo/odoo/blob/8.0/openerp/tools/convert.py#L727
* https://github.com/odoo/odoo/blob/8.0/openerp/tools/convert.py#L836

Mapping records that reference models are created at initializing modules/models/fields. As they lack a corresponding XML record and cannot declare its corresponding External ID by this means, the ORM creates its External ID based in the 'model_' prefix and the object's technical name (dots replaced by underscores):
* https://github.com/odoo/odoo/blob/8.0/openerp/models.py#L382

This is why records that reference models ('ir.model' records) have the following form: model_XXXXX

Records for some other resources also have known prefixes for their External IDs:

  • Modules: https://github.com/odoo/odoo/blob/8.0/openerp/modules/db.py#L90
  • Models: https://github.com/odoo/odoo/blob/8.0/openerp/models.py#L382
  • Fields: https://github.com/odoo/odoo/blob/8.0/openerp/models.py#L444

SELECT * FROM "ir_model_data" WHERE name LIKE 'module_%'; -- most are 'ir.module.module' records
SELECT * FROM "ir_model_data" WHERE name LIKE 'model_%' ORDER by module, name; -- all/most are 'ir.model' records
SELECT * FROM "ir_model_data" WHERE name LIKE 'field_%' ORDER BY module, name; -- all/most are 'ir.model.fields' records

Records for other resources may follow some convention or simply not:

SELECT * FROM "ir_model_data" WHERE name LIKE 'view_%' ORDER by module, name; -- all/most are 'ir.ui.view' records
SELECT * FROM "ir_model_data" WHERE model LIKE 'ir.ui.view' AND name NOT LIKE 'view_%' ORDER by module, name; -- 'ir.ui.view' records with unconventional names

I hope this helps you to clarify your doubts.

Regards,
Marvin

Avatar
Discard

+1 for prompt answer...

Author

Thanks a lot for the thorough answer Marvin. That's a lot of detailed info about Odoo I would have had a devil of a time digging up. I upvoted, and would set your answer to accepted, but the system won't let me.