Skip to content

Python snippets ​

Type odoo and a few words in a Python file, then pick a snippet to insert ready-made Odoo code. Snippets follow the Odoo version of your project, so the code you insert uses the right syntax.

These snippets come from the bundled Odoo Helper and support Odoo 18, 19 and 20.

What you can do ​

  • Insert a model class with the right base class and constraints for your version.
  • Add a field or a method with the common arguments already filled in.
  • Raise errors and show notifications with a ready-made block.
  • Add the usual imports with one keyword.
  • Move between placeholders with Tab.

Get started ​

  1. Open a Python file in an Odoo module.
  2. Type odoo and the name of what you need, for example odoo new model.
  3. Pick the snippet from the list. Use the arrow keys to move, press Enter or Tab to insert it, and press Esc to close the list.
  4. Press Tab to jump to each placeholder and fill it in.

Check the version in the status bar, for example Odoo v20 (Auto). Select it to change it. See Create modules and files for how the version is detected.

Models ​

SnippetWhat it insertsOdoo 18Odoo 19Odoo 20
odoo new model classA model with _name, _description and a name field. On Odoo 20 it also has _order, an active field and a unique-name constraint.YesYesYes
odoo classical inherited model classA new model that copies another with _name and _inherit.YesYesYes
odoo delegated inherited model classA model that embeds a parent record with _inherits and a Many2one link.YesYesYes
odoo extended inherited model classAn extension of an existing model with _inherit.YesYesYes
odoo abstract modelAn abstract model (a mixin with no table).YesYesYes
odoo transient modelA wizard model. On Odoo 20 it includes a confirm button method.YesYesYes
odoo sql constraints_sql_constraintsYes
odoo constraintmodels.Constraint, which replaces _sql_constraints.YesYes
odoo indexA database index with models.Index.Yes
odoo unique indexA unique index, optionally partial, with an error message (models.UniqueIndex).Yes
odoo controllerAn HTTP page route and a jsonrpc route.Yes

Fields ​

Type odoo and the field name, for example odoo many2one field. Each snippet has the common arguments filled in.

SnippetInserts
odoo boolean fieldfields.Boolean(string="Name", default=False)
odoo char fieldfields.Char(string="Name", required=False, translate=False)
odoo text fieldfields.Text(string="Name", translate=False)
odoo html fieldfields.Html(string="Name", sanitize=True, translate=False)
odoo integer fieldfields.Integer(string="Name", default=0)
odoo float fieldfields.Float(string="Name", digits=(16, 2))
odoo monetary fieldfields.Monetary(string="Name", currency_field="currency_id")
odoo date fieldfields.Date(string="Name", default=fields.Date.context_today)
odoo datetime fieldfields.Datetime(string="Name", default=fields.Datetime.now)
odoo selection fieldfields.Selection with three example choices and a default.
odoo many2one fieldfields.Many2one('res.partner', string="Name", ondelete='set null'). Choose set null, restrict or cascade from the list.
odoo one2many fieldfields.One2many('model.name', 'inverse_field_id', string="Lines")
odoo many2many fieldfields.Many2many('res.partner.category', string="Tags")
odoo binary fieldfields.Binary(string="File", attachment=True)
odoo image fieldfields.Image(string="Image", max_width=1024, max_height=1024)
odoo reference fieldfields.Reference with a list of models to choose from.
odoo json fieldfields.Json(string="Data")
odoo many2onereference fieldfields.Many2oneReference with a model_field. Odoo 20 only.

The values above are for Odoo 20. On Odoo 18 and 19, the snippets also add a help argument and, for most fields, tracking=True.

Methods ​

SnippetWhat it insertsOdoo 18Odoo 19Odoo 20
odoo create methodA create override that takes a list of value dictionaries (@api.model_create_multi).YesYesYes
odoo write methodA write override.YesYesYes
odoo unlink methodAn unlink override.YesYesYes
odoo onchange methodAn @api.onchange method.YesYesYes
odoo compute methodA computed field and its @api.depends method.YesYesYes
odoo constraints methodAn @api.constrains method that raises a ValidationError.YesYesYes
odoo default get methodA default_get override.YesYesYes
odoo action methodAn action_ method that returns a window action, for example for a smart button.YesYesYes
odoo ondelete methodAn @api.ondelete method that blocks deletion under a condition.Yes
odoo search name methodA _search_display_name override, so name search also matches another field.Yes
odoo display name methodA _compute_display_name method that changes how records are labelled.Yes

Typing @api. also offers each decorator as a ready-made method, for example @api.depends with a method below it.

Errors, notifications and actions ​

These are the same on Odoo 18, 19 and 20.

SnippetWhat it inserts
odoo validation errorraise ValidationError(...)
odoo user errorraise UserError(...)
odoo access errorraise AccessError(...)
odoo missing errorraise MissingError(...)
odoo redirect warningraise RedirectWarning(...) with an action ID and a button label.
odoo notificationA display_notification client action. Choose success, info, warning or danger.
odoo rainbow manThe rainbow man effect. Choose the fade-out speed.
odoo return actionA window action that opens a record, in the same view or in a dialog.
odoo url actionAn ir.actions.act_url action that opens a URL.

Each error snippet needs its import, for example from odoo.exceptions import ValidationError. Use the import snippets below.

Imports ​

SnippetInserts
odoo common imports or odoo import commonfrom odoo import api, fields, models
odoo import api, odoo import fields, odoo import modelsThe single import.
odoo import exceptionsfrom odoo.exceptions import UserError, ValidationError
odoo import httpfrom odoo import http
odoo import http requestfrom odoo.http import request
odoo import loggingimport logging and _logger = logging.getLogger(__name__)
odoo import tools, odoo import config, odoo import date_utilsImports from odoo and odoo.tools.
odoo import json, odoo import base64, odoo import re, odoo import datetime, odoo import htmlPython standard library imports.
odoo import werkzeug.utilsfrom werkzeug.utils import redirect

Examples ​

These are Odoo 20 outputs.

python
# odoo new model class
from odoo import api, fields, models


class ModelName(models.Model):
    _name = 'model.name'
    _description = 'Model Description'
    _order = 'name'

    name = fields.Char(string='Name', required=True)
    active = fields.Boolean(default=True)

    _name_uniq = models.Constraint('unique(name)', 'The name must be unique.')
python
# odoo compute method
field_name = fields.Char(string='Field Label', compute='_compute_field_name', store=True)

@api.depends('dependency_field')
def _compute_field_name(self):
    for record in self:
        record.field_name = value
python
# odoo ondelete method
@api.ondelete(at_uninstall=False)
def _unlink_except_done(self):
    for record in self:
        if record.state == 'done':
            raise UserError(self.env._("You cannot delete this record."))
python
# odoo notification
return {
    'type': 'ir.actions.client',
    'tag': 'display_notification',
    'params': {
        'title': self.env._("Title"),
        'message': self.env._("Message"),
        'type': 'success',
        'sticky': False,
    },
}
python
# odoo controller
from odoo import http
from odoo.http import request


class MyController(http.Controller):

    @http.route('/my_module/page', type='http', auth='user')
    def page(self, **kwargs):
        return request.render('my_module.template_id', {})

    @http.route('/my_module/data', type='jsonrpc', auth='user')
    def data(self, **kwargs):
        return {'records': request.env['res.partner'].search_read([], ['name'], limit=10)}

Tips and limits ​

  • Snippets use the Odoo version of the project. If a snippet you expect is missing, check the version in the status bar. For example, odoo constraint does not appear on Odoo 18.
  • Placeholders that appear more than once, such as a field name in a compute method, change together as you type.

Next steps ​

Built by Cybrosys Technologies.