How can I quickly get started and setup a first basic Odoo module?
Simply invoke ./odoo.py scaffold <module_name> <directory> on the command line. This will automatically create a basic module called <module_name> inside <directory>. The module name must be unique within the directory.
How can I execute custom SQL queries?
The cr attribute on environments is the cursor for the current database transaction and allows executing SQL directly (e.g. for queries which are difficult to express using the ORM or for performance reasons).
You can use self.env.cr.execute('SELECT * FROM table WHERE attribute=%s', [(value)]) and fetch the results in a for cycle by doing for results in self.env.cr.dictfetchall():.
What is a computed field?
Fields can have values calculated by a method, instead of simply reading a database stored value.
A computed field is declared just like a regular field, but has an additional argument computed with the name of the method used to calculate it like is_admin = fields.Boolean(compute="_compute_is_admin", store=False). If you want to store the computed field in the database, you can use store=True. You can also compute multiple fields at the same time by using the same method on all the computed fields and set the fields like self.field_1 = value_1, so on and so forth.
How can I show/hide a column in a tree view?
For showing user_id column in some tree, in the tree xml definition use <field name="user_id" invisible="context.get('invisible_user', True)"/>. In the search use <filter string="Show user" context="{'invisible_user': False}"/>.
How can I extend the existing Odoo models?
There are three different mechanisms to extend models:
Using _inherit but leaving out _name, the new model replaces the existing one, this is useful to add/customize fields/methods;
Using the _inherit and _name attributes together, Odoo creates a new model using the existing one (provided via _inherit) as a base, the new model gets all the fields and methods from its base;
Using the _inherits (note the additional "s") a model delegates the lookup of any field not found on the current model to "children" models.
The delegation is performed via reference fields automatically set up on the parent model and methods are not inherited, only fields.
How can I set a record field value by using expressions in an XML record?
You can use the eval attribute to evaluate a Python expression and assign the result value to the field like <field name="field_name" eval="python_expression_to_evaluate"/>.
How can I extend a view?
You need to set a new view and use the inherit_id field to identify the view you are extending like <field name="inherit_id" ref="target_view_id"/> before <field name="arch" type="xml"/>
You can then use XPath expressions to locate and insert/change/delete elements. Odoo also provides shortcut notations if you want to avoid XPath syntax like <field name="target_field" position="before"><field name="new_field"/></field>
The position attribute used with the locator element is optional, and can have the following values: after; before; inside; replace; attributes.
How can I change an inherit method on an extended model?
By declaring a method with the same name, the method will replace the previous one. In this case, it's best to avoid changing the method's parameters so the existing calls on it will keep working properly. In case you need to add additional parameters, you can make them optional with the default value keyword.
How can I change an inherit field on an extended model?
You can change an inherit field by adding a field with the same name on the extended model and set only the values for the attributes to be added/changed. The other attributes will remain unchanged.
How can I execute methods in an XML file during its load process?
An XML file can execute methods during its load process through the <function> element like <function model="model_name" name="method_name" eval="method_parameters"/>. We can use a tuple in the eval attribute to pass parameters to the method.
How can I automatically resize an uploaded image?
You can add a computed field like image = fields.Binary('Image', compute='_resize_image', store=True, attachment=True) and use the following methods (which are defined on tools) to automatically resize an image:
image_resize_image_big (1024x1024);
image_resize_image_medium (128x128);
image_resize_image_small (64x64);
You can define _resize_image method like self.image = tools.image_resize_image_medium(self.image) or you can also change the default width and height of the resized image by providing the default size value parameter on those methods like self.image = tools.image_resize_image_medium(self.image, size=(256, 256)).
How can I dynamically set field attributes in a form view based on another field’s value?
You can use the attrs attribute in a form field view to dynamically set its attributes based on another field’s value like <field name="field_name" attrs="{'field_attribute': field_domain}"/>.
The attrs takes a Python dictionary and maps element's attributes to domains. For example, you could hide a field like <field name="id" attrs="{'invisible': [('is_admin', '=', False)]}"/>
What is an external identifier?
All records in the database have a unique identifier, the id field, that is a sequential number automatically generated by the database engine.
Since we don't know these IDs beforehand (and we can need them to reference a related record), we use external named identifiers to translate these identifier names into the actual database IDs assigned to them.
The ir.model.data keeps the mapping between the named external IDs and their corresponding numeric database IDs.
How can I delete a data record in an XML file?
To delete a data record we use the <delete> element, providing it with either an id or a search domain to find the target record like <delete model="target_module" id="target_id"/> or <delete model="target_module" search="[('id','=',target_id)]"/>.
How can I translate an external ID into the corresponding database ID in an XML record?
You can use the ref attribute to translate an external ID into the corresponding database ID for a many-to-one relation field like <field name="field_name" ref="module_name.external_record_id"/>.
For a one-to-many or many-to-many relation field, a list of IDs is expected, so a different syntax is needed like <field name="field_name" eval="[(4, [ids])]"/>.
In the last case we use a list of triples, each triple is a write command that does different things according to the code used:
(0,0,{values}) link to a new record that needs to be created with the given values dictionary;
(1,ID,{values}) update the linked record with id=ID;
(2,ID) remove and delete the linked record with id=ID;
(3,ID) delete the relationship on the linked record with id=ID;
(4,ID) adds a relationship to existing record with id=ID;
(5) unlink all;
(6,0,[IDs]) replace the list of linked IDs.
What is the meaning of noupdate="1" attribute on <data> element in XML files?
It means that the records are created the first time they are loaded and in subsequent module upgrades nothing will be done to them. this is used so that certain records (e.g. a email template) can be changed by the user and are not altered after updating the server module.
Should I modify directly an existing module or use the inheritance mechanisms to extend it?
You shouldn't modify an existing module directly because doing so does not allow a clear separation between the original module and our modifications, making it difficult to apply changes or updates. You should use the inheritance mechanisms to extend modules.
Whats is the environment?
The environment stores various contextual data used by the ORM:
The database cursor for database queries;
The current user for access rights checking
The current context storing arbitrary metadata.
The environment also stores caches. All recordsets have an environment, which is immutable, can be accessed using env and gives access to the current user (cr), the cursor (cr) or the context (context).
What are XPath expressions used in the forms, templates and other XML records?
XPath expressions are expressions to select nodes in an XML document. We can use XPath expressions to locate, insert or delete elements in XML. You can find more in:
How can I add an icon to a module on the apps/modules list?
Place your .png icon in your_module_directory/static/description/icon.png. The default size is 200x200 pixels.
While in a form view, how can I execute a method by clicking in a form (action) button?
Declare a button like <button name="method_name" type="object" string="text_to_display_on_button"/> in the form then define the method with the same method name like def method_name(self):. Remember that methods must always return something, if they return None, client calls using the XMLRPC protocol won’t work. If you have nothing to return, it's common practice to return True.