1.问题描述

当我们使用filtered函数时,我们会传入一个字符串参数或者一个函数

  • 当传入一个字符串的时候,例子:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
so = self.env['sale.order'].sudo().search([('id', 'in', (148199, 251969))])

Out[1]: sale.order(148199, 251969)

In [2]: for s in so:
    ...:     print s.city_name
    ...:
False
邵阳市

In [3]: print so.filtered('city_name').city_name
邵阳市

两条记录,一条city_name有值,一个没有

当传入参数city_name时,会过滤掉city_name为空的记录

  • 当传入一个函数的时候,例子:
1
2
3
4
so.filtered(lambda self: self.city_name == '邵阳市')

In [11]: so.filtered(lambda self: self.city_name == '邵阳市')
Out[11]: sale.order(251969,)

返回执行函数返回值为True的记录

那么这是为什么呢???

2.源码及版本说明

python2.7

odoo9

贴出源码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def filtered(self, func):
"""
            选择“self”中的记录,使得“func(rec)”为真,并且
            将它们作为记录集返回。

            :param func:函数或点分隔的字段名称序列
"""
    if isinstance(func, basestring):
        name = func
        func = lambda rec: filter(None, rec.mapped(name))
    return self.browse([rec.id for rec in self if func(rec)])

3.代码分析

filter函数的使用

这里用的是filter函数第一个参数是None的情况,这种情况下,会过滤掉序列中的空值

例子:

1
2
3
4
In [1]: num_list = [2, 4, 0]
   ...: filter(None, num_list)

Out[1]: [2, 4]

当参数为字符串时

假设参数为city_name,会把city_name传入mapped函数中,这样最后会找出所有self实例的city_name值,然后过滤掉city_name为空的记录

当参数是函数时

这里直接对所有实例循环使用func方法,过滤空值

4.总结

filtered方法就是对mapped方法的封装,去除了不符合条件的值