Now we will add some logic to our buttons. This is done with Python code, using the methods in the model's Python class.
We should edit the todo_model.py
Python file to add to the class the methods called by the buttons. First, we need to import the new API, so add it to the import statement at the top of the Python file:
from odoo import models, fields, api
The action of the Toggle Done button will be very simple: just toggle the Is Done? flag. For logic on records, use the @api.multi
decorator. Here, self
will represent a recordset, and we should then loop through each record.
Inside the TodoTask
class, add this:
@api.multi def do_toggle_done(self): for task in self: task.is_done = not task.is_done return True
The code loops through all the to-do task records and, for each one, modifies the is_done
field, inverting its value. The method does not need to return anything, but we should have it to at least return a True
value. The reason is that clients can use XML-RPC to call these methods, and this protocol does not support server functions returning just a None
value.
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. Usually form buttons are expected to act only on the selected record, but in this case, we will want it also act on records other than the current one:
@api.model def do_clear_done(self): dones = self.search([('is_done', '=', True)]) dones.write({'active': False}) return True
On methods decorated with @api.model
, the self
variable represents the model with no record in particular. We will build a dones
recordset containing all the tasks that are marked as done. Then, we set the active
flag to False
on them.
The search
method is an API method that returns the records that meet some conditions. These conditions are written in a domain, which is a list of triplets. We'll explore domains in more detail in
Chapter 6
, Views - Designing the User Interface.
The write
method sets the values at once on all the 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 each of them one by one.
Now we should add tests for the business logic. Ideally, we want every line of code to be covered by at least one test case. In tests/test_todo.py
, add a few more lines of code to the test_create()
method:
# def test_create(self):
# ...
# Test Toggle Done
task.do_toggle_done()
self.assertTrue(task.is_done)
# Test Clear Done
Todo.do_clear_done()
self.assertFalse(task.active)
If we now run the tests and the model methods are correctly written, we should see no error messages in the server log:
$ ./odoo-bin -d todo -i todo_app --test-enable