Now we will add some logic to our buttons. Edit the todo_model.py
Python file to add to the class the methods called by the buttons.
We will use the new API introduced in Odoo 8.0. For backward compatibility, by default Odoo expects the old API, and to create methods using the new API we need to use Python decorators on them. First we need to import the new API, so add it to the import statement at the top of the Python file:
from openerp import models, fields, api
The Toggle Done button's action will be very simple: just toggle the Is Done? flag. For logic on a record, the simplest approach is to use the @api.one
decorator. Here self
will represent one record. If the action was called for a set of records, the API would handle that and trigger this method for each of the records.
Inside the TodoTask
class add:
@api.one def do_toggle_done(self): self.is_done = not self.is_done return True
As you can see, it simply modifies the is_done
field, inverting its value. Methods, then, can be called from the client side and must always return something. If they return None
, client calls using the XMLRPC protocol won't work. If we have nothing to return, the common practice is to just return the True
value.
After this, if we restart the Odoo server to reload the Python file, the Toggle Done button should now work.
For the Clear All Done button we want to go a little further. It should look for all active records that are done, and make them inactive. Form buttons are supposed to act only on the selected record, but to keep things simple we will do some cheating, and it will also act on records other than the current one:
@api.multi def do_clear_done(self): done_recs = self.search([('is_done', '=', True)]) done_recs.write({'active': False}) return True
On methods decorated with @api.multi
the self
represents a recordset. It can contain a single record, when used from a form
, or several records, when used from a list
view. We will ignore the self
recordset and build our own done_recs
recordset containing all the tasks that are marked as done. Then we set the active
flag to False
, in all of them.
The search
is an API method returning the records meeting some conditions. These conditions are written in a domain, that is a list of triplets. We'll explore domains in more detail later.
The write
method sets values at once on all elements of the recordset. The values to write are described using a dictionary. Using write
here is more efficient than iterating through the recordset to assign the value to them one by one.
Note that @api.one
is not the most efficient for these actions, since it will run for each selected record. The @api.multi
ensures that our code runs only once even if there is more than one record selected when running the action. This could happen if an option for it were to be added on the list view.