This document extends the official coding guidelines of Odoo and the OCA community. In case of conflicting instructions, this document takes precedence. The order of guideline application is as follows:
Odoo Guidelines → OCA Guidelines → This Document
-
Guidelines as a Decision Basis Always adhere to the established guidelines, processes, and team expertise when making decisions. Aim for solutions and compromises that benefit the project and the team.
-
Active Participation Team members must actively engage in project activities, discussions, and supporting colleagues on both work-related and general topics.
-
Task-Based Workflow
- All work must align with defined tasks. Each task must address a specific problem and have a clear goal.
- Tasks should have an assigned responsible party and must be updated regularly to reflect progress.
- Check and update the status of your tasks daily.
-
Result-Oriented Work
- Strive for a balance between quality and efficiency. Favor simple, maintainable solutions.
- Conduct additional analysis or training when needed. Share constructive criticism and opinions.
-
Documentation
- Maintain accurate and comprehensive project documentation to help users and team members navigate the system structure and functionality.
- Keep documentation up-to-date with any changes or additions.
-
Knowledge Sharing Share new insights, technologies, or solutions with the team to prevent redundant research or development efforts.
-
Error Reporting
- Report any errors found in the system promptly.
- Ensure that all errors are documented and analyzed.
-
Responsibility
- Be diligent in fulfilling your responsibilities and respect your colleagues’ time.
- Double-check your work before submitting it and prepare thoroughly for meetings.
-
Automation
- Apply the DRY (Don't Repeat Yourself) principle to automate routine tasks. Use shortcuts, tools, and scripts wherever possible. Delegate trivial tasks to AI or other automated solutions.
-
Quality Assurance
- Ensure the system is user-friendly, reliable, and error-free.
- Anticipate various use-case scenarios to minimize potential issues.
-
Initiative
- Share your ideas and critiques with the team.
- Seek out optimal solutions and improvements.
-
Continuous Learning
- Commit to personal and professional growth. Stay updated on relevant technologies and industry practices.
-
Professional Ethics
- Communicate respectfully and professionally. Value others' time and contributions.
-
Health and Well-Being
- Maintain a healthy work-life balance to ensure long-term productivity and satisfaction.
-
All work must solve clearly defined problems documented as tasks.
-
Tasks should include:
- Problem Statement: What needs to be solved?
- Goal: What is the expected outcome?
- Business/Technical Analysis: How will it be addressed?
-
Changes or deviations from the initial requirements should be documented in comments.
-
Regular tasks (e.g., training or meetings) should be grouped under general task categories.
-
Tasks should be completed based on their priority unless otherwise directed by the project manager.
-
Each task should include:
- Requirements: Problem description and objectives.
- Business and technical analysis of requirements.
- Comments: Any deviations or clarifications.
-
Unusual and complex solutions should be described in the specifications.
-
Include links to all relevant files, specifications, and resources.
-
Any deviations from the requirements should be recorded in the comments.
-
The results of discussion and clarification of requirements should also be recorded in the comments.
-
Use GitHub for code reviews, where results are logged and tasks transition to the testing phase.
- Urgent tasks assigned by the project manager.
- Code review and analysis.
- Bug fixes.
- Hight priority tasks.
- Low-priority tasks.
- Minimum-priority tasks.
- Tasks from backlog.
- Training and self-development.
Each task should pass through the following stages, though the order may vary depending on the context and requirements:
- Problem Definition: Clearly describe the issue at the task creation stage.
- Expected Result: Define the desired outcome during task creation or analysis.
- Business/Technical Analysis: Propose an approach considering business processes or technical constraints.
- Priority Setting: Assign a priority to the task at the creation or analysis stage.
- Comments: Document any deviations from the expected outcome or initial analysis.
- During testing, if an issue arises, revert the task status to "PROGRESS" and document the problem in a comment.
- If analysis is insufficient or incorrect, set the task to "TO ANALYSIS" and document the issue in comments.
- During code review, mark the pull request (PR) as "draft" and revert the task to "PROGRESS" if changes are required. Include a detailed explanation of the requested modifications.
- For changes in task requirements, repeat the analysis phase.
- Minor adjustments do not require re-analysis but must be documented in comments for review.
- For significant requirement changes in an unassigned task, create a new task.
- More than one responsible person may be assigned to Analysis and Code Review. By regulation or by verbal agreement.
Naming is a critical skill, often requiring additional resources or advice from colleagues to find the perfect name for an object.
A well-thought-out, clear, and concise name can save hours of work, prevent bugs caused by misunderstandings, reduce distractions, and accelerate learning for both the code author and future readers.
- Clarity and Purpose: Names should clearly communicate the purpose and structure of an object.
- Simplicity and Brevity: Aim for concise, simple, and complete names—there is almost always an ideal choice.
- Data Type Identification: Names should convey the data type, especially since dataclasses are not used:
partner_id– Represents aMany2onefield.is_confirm– Represents aBooleanfield.
- Method Intent: A method should perform one specific action, and its name should describe this action clearly:
- Examples:
get_...,set_...,check_...,_prepare....
- Examples:
- Avoid Redundancy: Avoid unnecessary context or parent property clarifications in child objects:
sale_order_line_idinsidesale_order– Incorrect.line_id– Correct.
- Specificity Over Generalization: Be explicit, especially when dealing with multiple similar objects:
responsible_idanduser_id– Ambiguous.responsible_user_id– Clear.is_confirm– Vague.is_state_confirm– Specific.get_domain– Generic.get_return_picking_domain– Specific.
- Alphabetical Grouping: Group related fields alphabetically by category:
- Example: Use
date_startinstead ofstart_dateso all date-related fields appear together. - Similarly, group quantities as
qty,qty_done,qty_return, etc., for easy access.
- Example: Use
Method names should reflect the action performed:
get_: For methods that return values.set_: For methods that assign values.action_: For methods that return an Odoo action dictionary.check_is_: For methods verifying a condition:- Example: check_is_state_confirm – Passes without error if the state is "confirmed."
check_if_: For methods verifying the absence of a condition:- Example: check_if_state_confirm – Raises an error if the state is "confirmed."
check_<method_name>: For methods performing multiple checks related to a specific functionality.- CRUD Methods: Follow Odoo ORM conventions:
- Examples:
create,write,unlink,update,read.
- Examples:
- Field-Specific Methods:
_compute_<field_name>,_inverse_<field_name>,_onchange_<field_name>: For computed, inverse, or onchange fields._check_<field_name>: For constraint checks._default_<field_name>or_get_default: For default field values.
_prepare_: For methods returning dictionaries for record creation:- Example:
_prepare_line_vals– Returns dictionaries for creating new lines.
- Example:
- Boolean Fields: Start with
is_orallow_. - Many2one Fields: End with
_id. - Many2many Fields: End with
_ids. - One2many Fields: End with
_line_ids. - Reserved Names: Avoid overwriting commonly used Odoo field names, such as:
create_date,uidand etc - Magic fields.state: Represents the status of a record.name: The record's name.display_name- Displayed name in relational fieldscurrency_id- currency. Default currency field in Monetaryuser_id: The user responsible for the record.partner_id: The related contact.sequence: For ordering records.active: Indicates whether a record is active.description- description or note to the recordnote- note or comment to the recordattachment_ids- related attachments or filespriority- priority of Selection with priority widgetparent_id,child_ids- parent record and child record, for hierarchical structure.orig_id,dest_id- next and previous record in chainstype- record type, e.g. contact, contract or event typedate_start,date_end: Represent start and end dates.date_start,date_end- start and end dates. There are of course variants and vice versastart_dateandend_date, but they will be poorly sorted alphabetically
- Variables must not be abbreviated. The exception is clear and frequently used abbreviations.
- Use the same naming style within the same module or project.
- Integer identifiers or arrays must end with
_idor_ids.partner # res.partner(7) partner_id # 7 partner_obj # res.partner() companies # res.company(1, 5, 20) company_ids # [1, 5, 20]
- PEP8: For all other cases not covered by this regulation, adhere to the naming standards defined in PEP8.
Examples:
-
Salesperson Field: A field storing the salesperson (a relation to
res.users):user– Too vague.user_id– Lacks clarity about the user's role.salesperson_id– Standard Odoo option but insufficient for clarity.salesperson_user_id– Ideal.salesperson_partner_id– Misleading about the data type.- s
alesperson_user_who_sell_item_id– Overly verbose.
-
Sales Order Lines: A field for storing the lines of a sale order:
lines– Ambiguous.sale_order_line_ids– Verbose and redundant (context already provided bysale_order).line_ids– Concise and clear.item_line_ids– Ideal, as it specifies the type of lines (items).product_line_ids– Misleading, as lines represent order items, not just products.
- Line Length: The maximum line length depends on the project, but it is generally set to 88 characters.
- Code Separation: Logically distinct sections of code should be separated by a blank line. It is recommended to comment on these sections for clarity.
- Attribute and Argument Order: The order of attributes should be consistent across classes, files, and modules.
- Commenting: Use docstrings to describe methods and functions. Comments should explain code blocks, fields, or any commented-out code, providing context for why the code is commented out.
- Quotation Marks: Prefer double quotes (
") over single quotes (') for consistency.
-
Class Structure Order:
- Class attributes, such as
_name,_orderand etc. - Default методы.
- Core relational fields, such as
line_ids,order_id. - Core non-relational fields, such as
name,display_name. - Other fields grouped by logical meaning.
- Property methods.
- Compute methods.
- Inverse methods.
- Onchange methods.
- Constrains methods.
- Business logic methods.
- Private methods.
- Overridden base methods (e.g.,
create,write,name_get,search_readetc.
- Class attributes, such as
-
Field Definitions:
- Use positional arguments only for primary field properties such as
relationandmodelinMany2one,Many2many,One2many, andselectioninSelection.
name = fields.Char(string="Name", readonly=True, copy=True) partner_id = fields.Many2one("res.partner", string="Partner") company_ids = fields.Many2many("res.company", string="Companies") line_ids = fields.One2many("model.line", "model_id", string="Lines") picking_ids = fields.Many2many("stock.picking", "stock_picking_model_rel", "picking_id", "model_id", string="Pickings")
- Use positional arguments only for primary field properties such as
-
Field Argument Order:
- Core field properties (e.g.,
comodel_name,selection). - Field computation properties (
relation,compute,inverse,search). - Additional field properties (e.g.,
readonly,copy,required). - Default values (
default). - Domain constraints (
domain). - Context settings (
context). - Groups (
groups). - Help text (
help).
- Core field properties (e.g.,
-
Inheritance:
- Promote field properties as high as possible in the inheritance chain —
mixin<-model<-view.
- Promote field properties as high as possible in the inheritance chain —
-
Overriding Base Methods:
- Maintain the original method signature and include comments explaining the reason for overriding above the method and inline.
-
Use the correct approach for translations in your modules.
-
In Odoo 16.0, store domain rules in a binary field to reuse them later in views. This avoids
@onchangewith return:domain{}. Example here. -
Use read_group with ['field:sum'] for PostgreSQL aggregation to improve performance.
-
In Odoo 16+, use the BaseCommon test class for improved context with tracking disabled and other optimizations.
-
Prefer computed fields with
readonly=Falseover@onchangefor dynamic behavior. -
When overriding computed fields, you don't need to explicitly add existing dependencies to
@api.depends. They will automatically merge.
Users are often unfamiliar with modern ERP systems and processes. However, most users are eager to learn the interface. Here's how we can help:
- Avoid cluttering the interface. Each new button, field, or text overloads the interface, making it less user-friendly. Replace flat structures with nested ones.
- Explain complex functionalities and field purposes using the
helpattribute or textual descriptions on forms. See the example of creating routes in Odoo (Inventory -> Configuration -> Routes -> New). - Pay attention to field naming consistency across forms. Use plural names for fields that allow multiple options (e.g.,
partner,partners). - Maintain a consistent appearance for menus, navigation, forms, and field orders.
- Build uniform logic and structure for interfaces, including button colors, names, statuses, value propagation, and overrides.
- Place complex or less relevant fields for specific users into separate tabs, settings, or groups.
- Address common user questions directly in the system:
- Why are fields highlighted in red?
- Why did a field auto-fill?
- Why can't I see or click a button?
- Why is a specific field missing?
- Use this template as a base for new modules.
- Include copyright information in all Python, XML, and JS files.
- Match the documentation format to the repository's standard. Prefer Markdown (
.md) over RST (.rst). - If adding screenshots, place them in the module's
/description/imgdirectory. See an example here. - Add demo data wherever feasible but avoid demo data in tests.
- Assign an appropriate category to your module.
- Ensure the following aspects are covered:
- Task Alignment: Verify that the code addresses the problem or requirements outlined in the task description.
- Error Detection: Check for any bugs, issues, or incorrect logic in the code.
- Optimization: Assess whether the code achieves its purpose in the most efficient manner.
- Best Practices: Ensure the code adheres to the provided coding standards and conventions.
- Documentation: Confirm that all functions are well-documented and the code is adequately commented.
- Provide meaningful suggestions:
- Suggestions should add value. Avoid requesting changes if the code complies with the standards but simply does not align with your preferences.
- Bad example: "Please replace
x=0withy=0because I likeybetter."
- Bad example: "Please replace
- Comments should provide clear reasoning:
- Bad example: "Fix this code" or
def use_this_function(self). - Good example: "This code could pose security risks, as it allows arbitrary code execution via
sudo(). To mitigate this, consider the following approach:<code_snippet>
- Bad example: "Fix this code" or
- Suggestions should add value. Avoid requesting changes if the code complies with the standards but simply does not align with your preferences.
- Avoid delegating research to the author:
- Bad example: "Please try this code
<code_snippet>; it might be faster." - Ensure you are confident in the necessity of requested changes before asking for them.
- Bad example: "Please try this code
- Use oca-port for porting OCA addons.
- Follow the recommendations provided in the OCA Wiki.
- When migrating a module to a new Odoo version:
- Avoid simultaneous code refactoring during the migration process.
- First, ensure the module functions correctly in the new version.
- Implement any refactoring or improvements only after verifying compatibility.
- What's new in Odoo versions? Find updates here.
- Squashing commits: Learn more here.
- Code Review Best Practices: Refer to Atlassian's guide. You can also search online for "how to do code reviews."
- Porting tools: Use oca-port for smooth module migration.
- Odoo IDE Plugin: Enhance development with the Odoo IDE plugin.