Skip to content

Odoo coding standards ​

Assista IDE can check your Python and XML files against Odoo's coding guidelines as you edit, so you catch naming and structure issues before a review. The warnings are off by default.

This feature comes from the bundled Odoo Helper. Read the guidelines themselves in the Odoo documentation.

What you can do ​

  • Catch naming issues in models, fields, methods, record IDs and file names.
  • Keep files consistent across your team, for example the import order and the order of attributes in XML.
  • See problems as you type, as warnings in the editor and in the Problems panel. Each warning shows the rule that was broken and the pattern to use.

Get started ​

  1. Open Settings.
  2. Search for Enable Code Standard Warnings.
  3. Turn it on.

The checks run on .py and .xml files when you open them, as you type and when you save. Every finding is a warning on the line that triggered it. Turn the setting off to clear all warnings.

What it checks ​

Python ​

Files and classes. These checks run on files in a models/ folder.

RuleExample
The file name is the snake_case form of the model class name.class CustomerInvoice goes in customer_invoice.py, not customerInvoice.py.
Class names use CamelCase.class CustomerInvoice, not class customer_invoice.
The _name of a model is singular.res.partner, not res.partners.
The _name of a transient model follows <base_model>.<action>.account.invoice.import. A name with no dot is flagged.

Fields

RuleExample
Many2one field names end in _id.customer_id = fields.Many2one('res.partner')
One2many and Many2many field names end in _ids.invoice_line_ids = fields.One2many(...), category_ids = fields.Many2many(...)

Methods

RuleExample
Compute methods start with _compute_._compute_total_amount
Search methods start with _search_._search_name
Default methods start with _default_._default_company_id
Selection methods start with _selection_._selection_state
Onchange methods start with _onchange_._onchange_customer_id
Constraint methods start with _check_._check_total_amount
Action methods start with action_.action_validate
action_ methods call self.ensure_one() near the start.def action_validate(self): self.ensure_one()

A method is flagged when its name contains one of the keywords (compute, search, default, selection, onchange, check or action) but does not start with the matching prefix. compute_total_amount is flagged, and so is a core override such as default_get. You can ignore the warning on those overrides.

Imports. Order imports in three groups: the Python standard library, then odoo, then odoo.addons.

python
import datetime
import logging

from odoo import api, fields, models
from odoo.addons.base.models import ir_model

Patterns to avoid

PatternUse instead
.clone()dict(my_dict) or list(my_list)
cr.commit()Let Odoo commit. Commit yourself only on a cursor you created.
_('Welcome %s' % name), formatting before translation_('Welcome %s', name)
_('Welcome ' + name), concatenation inside _()One complete string literal.
_('Welcome') % name, formatting after translationPut the values inside the _() call.
_('Name: %s' % _(name)), a nested _()Leave field values untranslated. Odoo translates them.
if len(records) > 0:if records:
for key in my_dict.keys():for key in my_dict:
my_dict.get('key', None)my_dict.get('key')

INFO

The translation check flags any % inside _(), including the recommended _('Welcome %s', name). If you follow the recommended form, you can ignore that warning.

XML ​

Elements and attributes

RuleExample
On a <record>, put id before model.<record id="customer_invoice_view_form" model="ir.ui.view">
On a <field>, put name first.<field name="invoice_number" type="char">
Put noupdate="1" on <odoo>, not on <data>.<odoo noupdate="1">
Use <menuitem>, not a record of ir.ui.menu.<menuitem id="customer_invoice_menu" .../>

IDs. A check applies to an ID when it contains the marker shown.

RecordPatternExample
Menu, ID contains _menu<model>_menu or <model>_menu_<detail>customer_invoice_menu_main
View, any ID inside an ir.ui.view record<model>_view_<type>, optionally ending in _inherit. The type is form, list, kanban, search, calendar, graph, pivot, activity or tree.customer_invoice_view_form
Action, ID contains _action<model>_action or <model>_action_<detail>customer_invoice_action
Group, ID contains _group_<module>_group_<name>invoice_group_manager
Rule, ID contains _rule_<model>_rule_<group>customer_invoice_rule_company

View names. In an ir.ui.view record, the name field uses dots and the form <model.name>.view.<type>, such as customer.invoice.view.form. For an inherited view, the name ends with .inherit.<details>, such as customer.invoice.view.form.inherit.partner.

File names ​

The check uses the name of the folder that holds the file.

FolderFiles must be named
views/ (XML)*_views.xml, *_templates.xml or *_menus.xml
security/ (XML)*_groups.xml or *_security.xml
report/ (XML)*_report_views.xml, *_reports.xml or *_templates.xml
wizard/ (XML)*_views.xml
data/ (XML)*_data.xml or *_demo.xml
controllers/ (Python)snake_case, such as main.py or portal.py
wizard/ (Python)snake_case
report/ (Python)*_report.py

Access files (ir.model.access.csv and, on Odoo 20, ir.access.csv) are CSV files and are not checked.

Tips and limits ​

  • Warnings are suggestions based on Odoo's guidelines. You decide what to change.
  • The checks only read .py and .xml files. They do not check CSV files.
  • Turn the setting off again at any time if the warnings are noisy for an older project.
  • Files that the file and module generators create can still trigger a few warnings, such as a placeholder view ID. Rename them as you fill in the template.

Next steps ​

Built by Cybrosys Technologies.