Server action can be used to call a python method that should work when we click on a menu item. Server action works on the base model specified as “model_id” and allows to trigger server code from any action.
The actions available includes:
Execute python code: this will execute a block of python code. We use this action here.
Create a new record: creates a new record in the given model.
Write on a record: updates the values of a record that already exists.
Execute several actions: this action allows to define an action that will trigger the execution of several other server actions.
In this example, we are going to use "execute python code" action. Here, I have created a python function named “test_function” that works when we click on the menu named ”Accessories”.
For this, first, we create a menu item with the name "accessories" and link it to action ”category_python_action”. Then we create a server action with id “category_python_action” and specify the base model on which the function should work by giving the model_id. We specify the function to be called in the code section.
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="category_python_action" model="ir.actions.server">
<field name="name">Category Accessories</field>
<field name="model_id" ref="product.model_product_product"/>
<field name="state">code</field>
<field name="code">
action = model.test_function()
</field>
</record>
<menuitem id="category_python_action_menu" name="Accessories" action="category_python_action"/>
</data>
</odoo>
Keys available in the evaluation context includes a model (object of the model specified in model_id), record/records ( records on which the action should be triggered), env( odoo environments).
Now that we have the action all set for the work, we can now define the python function inside the model we specified in the action. The function should be inside the model that we specified in the model_id field. Here I have created a function to filter products that belong to the accessories category( with id 5) and return the view for it.
from odoo import models
class ProductTest(models.Model):
_inherit = "product.product"
def test_function(self):
categories = self.env['product.category'].search([('id', '=', 5)]).ids
return {
'name': 'Accessories',
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'kanban,tree,form',
'domain': [('categ_id', 'in', categories)],
'res_model': 'product.product',
'target': 'current'
}
We will need this case when we can't get the required filtering via XML or any situation where python code is required to get a specific task done.
The output of the code will create a menu item named accessories that will show products that belong to the accessories category when clicked on it. This is because we have filtered the records of the product.
Product with category accessories by using the domain filtered with accessories category id 5.
This is just a simple example to demonstrate the way to execute the python function by calling it from XML using server action. We can also create the server action from the user interface by going to settings -> technical -> actions -> server actions.