- The difference between one, several, and a model
In fact, you can call the @api.one method with a RecordSet containing multiple entries. The only difference is that with @api.one the write loop will be executed outside the function that you define, and as a self decorator will pass each record to the RecordSet one at a time.
As an example, let's define two functions in our example.model model:
@api.one print_self_one(self): print self @api.multi print_self_multi(self): print self
And call them like this: odoo shell :
model = env['example.model'] record_set = model.browse(1,2) print "record set: " + record_set print "using @api.one:" record_set.print_self_one() print "using @api.multi:" record_set.print_self_multi()
Will return:
record set: example.model(1,2) using @api.one: example.model(1) example.model(2) using @api.multi: example.model(1,2)
Thus, the following two are equivalent:
@api.one _compute_name(self): self.name = "Default Name" @api.multi print_self_multi(self): for record in self: record.name = "Default Name"
even if thery is called with a larger record in the recordset.
On the other hand, you are not using a decorator, then it cannot be called more (or less) than one record, or it will complain and probably stop with an error.
@api.model is a completely different story: you should use this decorator only if you expect it to be called with an empty recordset.
If you expect a non-empty RecordSet as an input value, then in many cases you can use both @api.one and @api.multi , this is just a matter of personal preference. I personally prefer to use @api.one whenever possible because I find the code much cleaner this way (also for calculation methods and onchange, the Odoo source usually uses @api.one ).
There are a few cases where you can use @api.multi , though:
If you not only want to loop records, but also want to do something only once:
@api.multi print_self_multi(self): print "this will only be printed once" for record in self: print "this will be printed len(record_set) times"
If the return value is important. A function decorated with @api.one will always return a list (a list of return values in your function as an iteration). However, in some cases, especially when interacting with the graphical interface, you will have to return the dictionary (for example, with a warning). In these cases, you will have to switch from @api.multi .