OD310 unmatched-view-locator¶
An inherited view locates an element its parent views do not have.
| Category | Severity | Series | Needs the index |
|---|---|---|---|
| Correctness | Error | all | yes |
What it reports¶
A spec in an inherited view, such as <field name="x" position="after"> or an <xpath>, that
names an element by its name, id or t-call when no such element is in the view it extends, in
that view's own parents, or in the other views of the dependency graph that extend them. Each named
step of an xpath, such as group[@name='x'] or t[@t-call='x'], must match. A spec that finds the
element only in a view added by a module missing from depends is reported too. A module that Odoo
always installs with base, such as web, counts as in depends.
Place makes a spec, not position, which defaults to inside. A spec is the root of an inherited
arch, each child of a <data> root, or each child of a <template> with a non-empty inherit_id.
What a spec holds is content, and so is what a view without a parent holds, whatever position it
carries: from 19.0 on that is a parameter of a t-call. Only a position="move" child of a spec
locates. A <template t-call="x"> without a parent has the element <t t-call="x"> as its root. A record
whose inherit_id is eval="False", an empty ref or no value at all has no parent, so its arch
holds elements and no spec.
Only a file Odoo loads gives a parent or an extension: one the manifest lists under a key the
module's series reads, as OD502 tabulates, or one the module loads itself. A file whose
name appears in the module's Python code counts, whatever key lists it, as that code loads it (18.0
addons/hr/models/hr_employee.py:696). So does a chart template under data/template/, on every
series though Odoo reads one from saas~16.2. A file listed under a key Odoo loads nothing from, such
as other_files, counts unless a legacy key the series ignores lists it too, as it was meant to
load from there. 18.0 reads data and not update_xml (odoo/modules/loading.py:39-48), so a file
under update_xml and other_files counts as unlisted there, while 9.0
(openerp/modules/loading.py:60-64) and 10.0 (odoo/modules/loading.py:57-61) load it. An element
that only an extension in any other file adds is reported: list that file under data.
Why it matters¶
Odoo applies the specs when it builds the view, and a spec that matches nothing stops the install
with Element '<field name="x">' cannot be located in parent view. A demo file differs: see load
failures. When the element comes from a
module outside depends, the view builds where that module is installed and breaks where it is not.
The cause is usually a typo, or an element that the parent module renamed or removed in a new
series, which a port carries over unnoticed until the install.
The rule only checks what it can match exactly. An xpath with | or or, a step without a
name, id or t-call, a spec on a parent view outside depends, which is
OD302's to report, and a spec on a parent found only in a file Odoo does not load, are
left alone. A field locator matches a field anywhere in the parent, subviews included, as it does
in Odoo.
The rule stays silent on a tree of views that a dependency that is not indexed, such as an
Enterprise module, could add the element to. It still reports a tree whose root the module defines,
as on a model the module defines whole, since that dependency loads first and cannot extend it.
Add the checkout of the dependency that is not indexed to --addons-path to check the other trees.
Example¶
<field name="arch" type="xml">
<field name="payment_terms_id" position="after">
<field name="client_order_ref"/>
</field>
<xpath expr="//group[@name='sale_heading']" position="inside">
<field name="commitment_date"/>
</xpath>
</field>
The sales order form has a payment_term_id field and a sale_header group, so neither spec
finds its element.
<field name="arch" type="xml">
<field name="payment_term_id" position="after">
<field name="client_order_ref"/>
</field>
<xpath expr="//group[@name='sale_header']" position="inside">
<field name="commitment_date"/>
</xpath>
</field>