OD209 model-redefined¶
A class redefines a model that a module in depends already defines.
| Category | Severity | Series | Needs the index |
|---|---|---|---|
| Correctness | Error | all | yes |
What it reports¶
A class that introduces a model one of the module's dependencies already defines, without naming
that model in _inherit: a class with _name, or one without it that Odoo names, as below. A
class without _name whose _inherit has an entry that is not a string literal is read as
extending its first literal entry, since the entries decide its name up to 18.0 and whether it is
new from saas~18.1. A module that Odoo always installs with base, such as web, counts as in
depends. Within the module itself, a second class that introduces the same model is reported when
it comes after the first in the same file; the order of separate files is that of the imports,
which the index does not record.
Why it matters¶
Odoo treats a class whose _name is not among its _inherit as the definition of a new model. A
class without _name and with a list or tuple _inherit gets a name too. Up to 18.0, a one-entry
list names the model the class extends, and a longer list the class name verbatim. From saas~18.1
the name is the class name, lowercased, with a dot before each capital that is not its first
character and does not follow _, so ResPartner names res.partner whatever the list holds.
Odoo builds a fresh model from a class that defines one, the parents its _inherit names and
base, and puts it in the registry in place of the existing one, so every field and method the
earlier modules gave the model is gone. Their views and related fields that use a lost field then
fail to load, their code fails when it reaches one, and the database columns behind the lost fields
are left without a field.
Setting _inherit to the same name, or _inherit = _name, extends the model and is not reported.
Neither is a model that only modules outside the dependencies define: two modules that do not
depend on each other may each be installed alone.
Example¶
class ProductTemplate(models.Model):
_name = "product.template"
_description = "Product"
warranty_months = fields.Integer()
product already defines product.template, so this class replaces the model instead of adding a
field to it.
class ProductTemplate(models.Model):
_inherit = "product.template"
warranty_months = fields.Integer()