---
url: https://docs.cybrosys.com/vs-code-extension/snippets.md
description: >-
  Reference of Odoo Python and XML snippets in Odoo Helper for VS Code, by Odoo
  version 18, 19 and 20.
---

# Snippets

Insert Odoo models, fields, methods, views, actions and menus by typing `odoo` and choosing a snippet. Snippets follow the Odoo version of your project (18, 19 or 20).

## What you can do

All snippet prefixes start with `odoo`. Keep typing to narrow the list, for example `odoo form view` or `odoo char field`. The suggestion list shows a short description, and many snippets show documentation next to it. Press **Tab** to move between placeholders.

The tables below mark the versions that offer each snippet. A snippet that only one version offers does not appear on the others.

### Python models

| Prefix | Inserts | 18 | 19 | 20 |
|---|---|:-:|:-:|:-:|
| `odoo new model class` | A model with `_name`, `_description`, `_order`, `name` and `active` fields, and a unique-name constraint. | Yes | Yes | Yes |
| `odoo classical inherited model class` | A new model that copies another one (`_name` and `_inherit`, own table). | Yes | Yes | Yes |
| `odoo delegated inherited model class` | A new model that embeds a parent record (`_inherits`). | Yes | Yes | Yes |
| `odoo extended inherited model class` | An extension of an existing model (`_inherit`, same table). | Yes | Yes | Yes |
| `odoo abstract model` | An abstract model (mixin) with no table. | Yes | Yes | Yes |
| `odoo transient model` | A wizard model with a confirm button method. | Yes | Yes | Yes |
| `odoo sql constraints` | `_sql_constraints`. | Yes | | |
| `odoo constraint` | `models.Constraint`, which replaces `_sql_constraints`. | | Yes | Yes |
| `odoo index` | A database index (`models.Index`). | | | Yes |
| `odoo unique index` | A unique, optionally partial, index with an error message (`models.UniqueIndex`). | | | Yes |
| `odoo controller` | An HTTP controller with a page route and a JSON-RPC route. | | | Yes |

### Python fields

These are available in all versions. Choose them with `odoo <type> field`.

| Prefix | Inserts |
|---|---|
| `odoo boolean field` | A true or false value. |
| `odoo char field` | Short text, optionally translatable. |
| `odoo text field` | Long plain text. |
| `odoo html field` | Rich text, sanitized by default. |
| `odoo integer field` | A whole number. |
| `odoo float field` | A decimal number, with a precision. |
| `odoo monetary field` | An amount in a currency. The model needs the currency field it names, such as `currency_id`. |
| `odoo date field` | A date, with no time. |
| `odoo datetime field` | A date and time, stored in UTC. |
| `odoo selection field` | A choice from a fixed list of value and label pairs. |
| `odoo many2one field` | A link to one record of another model, with `ondelete`. |
| `odoo one2many field` | The records of another model that point back through their `Many2one`. |
| `odoo many2many field` | Links to any number of records of another model. |
| `odoo binary field` | File content, stored as an attachment. |
| `odoo image field` | An image resized to fit `max_width` and `max_height`. |
| `odoo reference field` | A link to a record of one of several models. |
| `odoo json field` | A JSON value. |
| `odoo many2oneReference field` | A record ID whose model comes from a `Char` field (Odoo 20 only). |

The field classes and parameters you get when you type `fields.` and `=` also follow your version. See [Smart suggestions](/vs-code-extension/features/smart-suggestions).

### Python methods

| Prefix | Inserts | 18 | 19 | 20 |
|---|---|:-:|:-:|:-:|
| `odoo create method` | An override of `create` with `@api.model_create_multi`. | Yes | Yes | Yes |
| `odoo write method` | An override of `write`. | Yes | Yes | Yes |
| `odoo unlink method` | An override of `unlink`. | Yes | Yes | Yes |
| `odoo onchange method` | An `@api.onchange` method. | Yes | Yes | Yes |
| `odoo compute method` | A computed field with its `@api.depends` method. | Yes | Yes | Yes |
| `odoo constraints method` | An `@api.constrains` method that validates records. | Yes | Yes | Yes |
| `odoo ondelete method` | An `@api.ondelete` method that blocks deletion under a condition. | | | Yes |
| `odoo search name method` | A `_search_display_name` method that makes name search match another field. | | | Yes |
| `odoo display name method` | A `_compute_display_name` method that sets the record label. | | | Yes |
| `odoo default get method` | An override of `default_get`. | | | Yes |
| `odoo action method` | A method that returns a window action, for example from a smart button. | | | Yes |

Typing `@api.` offers each decorator as a ready-made method, for example `@api.depends` with a `def` below it. The decorators offered follow your version.

| Version | Decorators |
|---|---|
| 18 | `autovacuum`, `constrains`, `depends`, `depends_context`, `model`, `model_create_multi`, `onchange`, `ondelete`, `private`, `readonly`, `returns` |
| 19 and 20 | The same, without `returns` |

### Python errors, notifications and actions

These are available in all versions. They use `self.env._()` for translation.

| Prefix | Inserts | Needs |
|---|---|---|
| `odoo validation error` | `raise ValidationError(...)` | `from odoo.exceptions import ValidationError` |
| `odoo user error` | `raise UserError(...)` | `from odoo.exceptions import UserError` |
| `odoo access error` | `raise AccessError(...)` | `from odoo.exceptions import AccessError` |
| `odoo missing error` | `raise MissingError(...)` | `from odoo.exceptions import MissingError` |
| `odoo redirect warning` | A warning with a redirect button. | `from odoo.exceptions import RedirectWarning` |
| `odoo notification` | A `display_notification` client action with a title, message, type and sticky flag. Return it from a button method. | |
| `odoo rainbow man` | The rainbow man effect. Return it from a button method. | |
| `odoo return action` | An `ir.actions.act_window` that opens a record, in a dialog with `target` set to `new`. | |
| `odoo url action` | An `ir.actions.act_url` that opens a URL. | |

### Python imports

Type `odoo` in a `.py` file to get these import snippets.

| Prefix | Inserts |
|---|---|
| `odoo common imports` | `from odoo import api, fields, models` |
| `odoo import fields` | `from odoo import fields` |
| `odoo import models` | `from odoo import models` |
| `odoo import api` | `from odoo import api` |
| `odoo import tools` | `from odoo import tools` |
| `odoo import config` | `from odoo.tools import config` |
| `odoo import date_utils` | `from odoo.tools import date_utils` |
| `odoo import common` | `from odoo import api, fields, models` |
| `odoo import http` | `from odoo import http` |
| `odoo import http request` | `from odoo.http import request` |
| `odoo import logging` | `import logging` and `_logger = logging.getLogger(__name__)` |
| `odoo import json` | `import json` |
| `odoo import base64` | `import base64` |
| `odoo import datetime` | `from datetime import datetime, date, timedelta` |
| `odoo import html` | `from html import escape` |
| `odoo import re` | `import re` |
| `odoo import werkzeug.utils` | `from werkzeug.utils import redirect` |
| `odoo import exceptions` | `from odoo.exceptions import UserError, ValidationError` |

### XML

These are available in all versions.

| Prefix | Inserts |
|---|---|
| `odoo xml` | An `<odoo>` data file. |
| `odoo record` | A record of any model. |
| `odoo form view` | A form view. |
| `odoo list view` | A list view. |
| `odoo pivot view` | A pivot view. |
| `odoo calendar view` | A calendar view. |
| `odoo graph view` | A graph view. |
| `odoo search view` | A search view with a filter and a group by. |
| `odoo kanban view` | A kanban view. |
| `odoo view inherit` | An inherited view. |
| `odoo xpath` | An `xpath` for view inheritance. |
| `odoo action` | A window action. |
| `odoo menu root` | An app (root) menu with an icon. |
| `odoo menu category` | A menu with sub-menus. |
| `odoo menu action` | A menu that opens an action. |
| `odoo sheet` | A form sheet. |
| `odoo header` | A form header with buttons and a status bar. |
| `odoo notebook` | A notebook with a page. |
| `odoo page` | A notebook page. |
| `odoo chatter` | The chatter. The model must inherit `mail.thread`. |
| `odoo button box` | A container for smart buttons. |
| `odoo smart button` | A smart button. |
| `odoo object button` | A button that calls a model method. |
| `odoo action button` | A button that opens an action. |
| `odoo label` | A field label. |
| `odoo field` | A field. |
| `odoo field widget` | A field with a widget. |
| `odoo field invisible` | A field hidden by a condition. |
| `odoo field readonly` | A field made read-only by a condition. |
| `odoo field required` | A field required by a condition. |
| `odoo field state` | A status bar. |
| `odoo options` | Field options. |
| `odoo domain` | A domain attribute. |
| `odoo groups` | A group restriction. |

Odoo 20 adds these:

| Prefix | Inserts |
|---|---|
| `odoo editable list` | An inline-editable list view. |
| `odoo field optional` | An optional list column. |
| `odoo column invisible` | A list column hidden by a condition on the parent. |
| `odoo ribbon` | A ribbon widget. |
| `odoo settings` | A settings app, block and setting inside `base.res_config_settings_view_form`. |
| `odoo report` | A report action. |
| `odoo cron` | A scheduled action. |
| `odoo access` | An `ir.access` rule. With no group, it restricts everyone. |

## Get started

1. Open a `.py` or `.xml` file in an Odoo module.
2. Type `odoo` and pick a snippet from the suggestions.
3. Fill the placeholders with **Tab**.

### Examples (Odoo 20 output)

```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 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,
    },
}
```

```xml [odoo kanban view]
<record id="model_name_view_kanban" model="ir.ui.view">
    <field name="name">model.name.view.kanban</field>
    <field name="model">model.name</field>
    <field name="arch" type="xml">
        <kanban sample="1">
            <templates>
                <t t-name="card">
                    <field name="name" class="fw-bold fs-5"/>
                </t>
            </templates>
        </kanban>
    </field>
</record>
```

```xml [odoo access]
<record id="access_model_name_user" model="ir.access">
    <field name="name">model.name user</field>
    <field name="model_id" ref="model_model_name"/>
    <field name="group_id" ref="base.group_user"/>
    <field name="operation">crud</field>
    <field name="domain">[(1, '=', 1)]</field>
</record>
```

### Constraints by version

**Odoo 20**

```python
_name_uniq = models.Constraint(
    'unique(name)',
    'The name must be unique.',
)
```

Odoo 20 also offers `odoo index` and `odoo unique index`.

**Odoo 19**

```python
_name_uniq = models.Constraint(
    'unique(name)',
    'The name must be unique.',
)
```

**Odoo 18**

```python
_sql_constraints = [
    ('name_uniq', 'unique(name)', 'The name must be unique.')
]
```

## Tips and limits

* Snippets that only one version offers do not appear on the others. For example, `odoo sql constraints` appears on Odoo 18, and `odoo constraint` on 19 and 20.
* If no snippets appear, check the Odoo version in the status bar and that the file is recognised as Python or XML.
* Some snippets need an import. Type `odoo import exceptions` to add the exception classes.
* Insert `odoo chatter` only in a form view of a model that inherits `mail.thread`.

## Next steps

* [Smart suggestions](/vs-code-extension/features/smart-suggestions)
* [Model tools](/vs-code-extension/features/model-tools)
