Low-code customization (Studio-style)¶
Odoo Studio is a visual editor exclusive to Enterprise. The customizations it makes (fields, views, automated actions) are ordinary Odoo records stored in the database. This plugin creates those same records over RPC, so you get the usual Studio results in Community too, without the license.
Honest scope
This covers small, low-code changes: a field, a view tweak, a simple automation. It does not replace serious module development (packaged code, migrations, tests, complex business logic). For that, build a module. See Is it like Odoo Studio?.
Where the changes live¶
In the instance/database, exactly like Studio, not as module code in a repository. They survive updates as manual customizations. If you need code in a repository, that is module development and falls outside the scope of this plugin.
1. Add a custom field¶
Use the odoo_add_field tool. It creates a field with state='manual' and forces
the required x_ name prefix.
odoo_add_field {
"model": "res.partner",
"name": "loyalty_points",
"label": "Puntos de lealtad",
"field_type": "integer"
}
The name loyalty_points becomes x_loyalty_points.
Relational example:
odoo_add_field { "model": "res.partner", "name": "account_manager",
"label": "Ejecutivo de cuenta", "field_type": "many2one", "relation": "res.users" }
For a selection field, pass selection as [["a","A"],["b","B"]]. After creating
the field, add it to a form or list view (step 2) so users can see it.
2. Adjust a view (inherited)¶
There is no dedicated tool; use odoo_create on ir.ui.view with an inherited
arch so you do not overwrite the base view. First find the view to extend:
odoo_search_read { "model": "ir.ui.view",
"domain": [["model","=","res.partner"],["type","=","form"]],
"fields": ["name","xml_id"], "limit": 5 }
Then create an inherited view:
odoo_create { "model": "ir.ui.view", "values": {
"name": "res.partner.form.x_loyalty",
"model": "res.partner",
"inherit_id": <id_vista_base>,
"arch_db": "<xpath expr=\"//field[@name='email']\" position=\"after\"><field name=\"x_loyalty_points\"/></xpath>"
}}
Prefer xpath ... position="after|before|inside|replace" instead of rewriting the
whole view.
3. Add an automation¶
Use odoo_add_automation. The Python runs under Odoo's safe_eval; the tool
validates it before sending, which matters above all in Odoo online/SaaS, where
arbitrary Python is rejected server-side.
odoo_add_automation {
"model": "crm.lead",
"name": "Marcar leads calientes",
"trigger": "on_create_or_write",
"code": "for rec in records:\n if rec.probability and rec.probability > 80:\n rec.priority = '3'"
}
safe_eval rules (enforced by the tool)
The code runs under Odoo's safe_eval. Forbidden: import, def,
class, return, with, and access to names or attributes that start with an
underscore or dunder (__). The tool rejects those constructs before
sending, with a clear remediation, so you find out locally instead of through a
server error.
Available names in that context: env, model, record/records,
datetime, dateutil, time, UserError. To return an action, assign
action = {...} as the last statement (never return).
Enterprise vs Community¶
- The fields, views and automations created here work in both editions.
- In Enterprise they will not appear inside the Studio editor (they are not
tagged as
web_studiocustomizations), but they behave the same at runtime. - The models exclusive to Enterprise (for example
documents.document) still cannot be used in Community: the compatibility layer raises a clear error.
Verify (definition of done)¶
Read the record back and confirm the effect:
- Field:
odoo_fields_get { "model": "<modelo>" }shows the newx_field. - View: open the form in Odoo (or read the inherited
ir.ui.view). - Automation: trigger it on a record and read the modified field.
Skill reference: /odoo-tools:odoo-studio-style.