In some cases, you already have a recordset, but you need to operate only on some records. You can, of course, iterate on the recordset, checking for the condition on each iteration and acting depending on the result of the check. It can be easier, and in some cases, more efficient to construct a new recordset containing only the interesting records and calling a single operation on that recordset.
This recipe shows how to use the filter()
method to extract a recordset from another one.
We will reuse the simplified res.partner
model shown in the Create new records recipe previously. This recipe defines a method to extract partners having an e-mail address from a supplied recordset.
In order to extract records with an e-mail address from a recordset, you need to perform the following steps:
@api.model def partners_with_email(self, partners):
def predicate(partner): if partner.email: return True return False
filter()
as follows:return partners.filter(predicate)
The implementation of the filter()
method of recordsets creates an empty recordset in which it adds all the records for which the predicate function evaluates to True
. The new recordset is finally returned. The order of records in the original recordset is preserved.
The preceding recipe used a named internal function. For such simple predicates, you will often find an anonymous lambda function used:
@api.model def partners_with_email(self, partners): return partners.filter(lambda p: p.email)
Actually, to filter a recordset based on the fact that one attribute is truthy in the Python sense, you can use partners.filter('email')
.