Skip to content

OD304 unknown-view-field

A view references a field its model does not have.

Category Severity Series Needs the index
Correctness Error all yes

What it reports

A <field> in a view's arch whose name is not a field of the model at that place: the view's model, or inside an x2many field's subview, that field's comodel, also when an extension adds the subview directly inside a field of the parent view. It also reports a field that only a module missing from depends adds. For an inherited view without a model, the model is the parent view's. A module that Odoo always installs with base, such as web, counts as in depends.

Why it matters

Odoo validates every view when it loads it, and a field the model does not have stops the install with Field "x" does not exist in model "y". A demo file differs: see load failures. When the field comes from a module outside depends, the view validates where that module is installed and breaks where it is not. The cause is usually a typo, or a field renamed in a new series.

A <field> used as a locator, with a position attribute, finds an element of the parent view instead of adding one, and OD310 checks it. The rule skips a place whose model it cannot tell, such as the inside of a spec on a list or kanban element, which may land in the main view or in any subview, and views on a model no indexed module defines. The fields of a diagram are not checked, as Odoo reads them on the models its node and arrow name and not on the view's. A spec locates the first field of that name anywhere in the parent view, so the rule also skips a subview an extension adds inside a field when a subview of the inheritance tree is on a model that may have that field too: the comodel may be another one.

The rule stays silent on a model that a dependency that is not indexed, such as an Enterprise module, could add the field to. It still reports a name that fails on a model the module defines whole, with every class and parent in the module, since that dependency loads first and cannot extend it. It also still reports a path that continues past a field that is not relational. Add the checkout of the dependency that is not indexed to --addons-path to check the other models.

A model may hold a field the scan cannot see, so a field missing from a model is not reported when a class of it, or of a model it inherits or delegates to, has a parent the scan cannot read or one no indexed module defines, or when a module in scope loads an unread data file, which may add a field to any model. One of a dependency loads first, so it cannot add to a model the module defines whole. A plain class the file defines above the model, which the scan can read as holding no field, hides nothing, so a typo on that model is reported. A model the module builds at runtime, as OD202 describes, is skipped too, for a field missing from it and for one depends does not reach, unless a class in scope introduces it with _name. A path is judged at the model where it fails, so a typo past a relation is reported when the comodel is seen whole. Any other field depends does not reach, and a path that continues past a field that is not relational, are reported whatever the parents. A class in scope in a file that does not parse counts as one the scan cannot read, so a field depends does not reach is left alone on its model. To keep a model under the check, put the module that defines a parent on the addons path, or define the parent as OD210 describes.

A field an ir.model.fields record adds counts on the record's model and on the models that inherit or delegate to it, wherever the module or its depends load the record, so a view that loads first is not reported though Odoo refuses it on install. When only a run tells the record's model, the field counts on every model. Only a manual record, the default, with an x_ name and a model_id adds a field: any other record, or one in a file Odoo does not load, leaves the name reported. A demo record counts only for a demo file, as demo data loads after the data and not on every database. What Odoo reads as it sets up a model counts only a record of a dependency, as OD203 describes.

Example

views/sale_order_views.xml
<record id="view_order_form_customer_ref" model="ir.ui.view">
    <field name="name">sale.order.form.customer.ref</field>
    <field name="model">sale.order</field>
    <field name="inherit_id" ref="sale.view_order_form"/>
    <field name="arch" type="xml">
        <field name="payment_term_id" position="after">
            <field name="customer_reference"/>
        </field>
    </field>
</record>

sale.order has no customer_reference field; the customer's reference is client_order_ref.

views/sale_order_views.xml
<record id="view_order_form_customer_ref" model="ir.ui.view">
    <field name="name">sale.order.form.customer.ref</field>
    <field name="model">sale.order</field>
    <field name="inherit_id" ref="sale.view_order_form"/>
    <field name="arch" type="xml">
        <field name="payment_term_id" position="after">
            <field name="client_order_ref"/>
        </field>
    </field>
</record>

Suppressing

<!-- odooscan: ignore[OD304] -->

See suppressing a finding.