简介:我们在使用关联字段时有时候需要对关联的记录进行筛选显示或者更改关联字段的显示值,我这里整理了四种方法方便大家参考。
场景1:针对不同的群体,many2one字段显示出来可供选择的记录不同
场景2:不想用odoo默认的many2one字段显示值,想自定义显示值
1.定义一个many2one类型的字段
name = fields.Many2one(string='员工', comodel_name='hr.employee', domain=lambda self:[], default=_get_user_employee)
2. many2one下拉列表筛选方法:
第一种:使用odoo自带的domain参数进行筛选,这种方式是程序一运行就会执行,没办法根据实际的参数设置筛选条件,所以只能实现固定筛选。
例如:
name = fields.Many2one(string='员工', comodel_name='hr.employee', domain=[('name', '=', '小明')])
第二种:通过 @api.onchange 实现值筛选
优点:可以实现动态条件触发,一个字段改变引起另一个字段相应变化
缺点:需要字段变化才能触发,记录创建时会触发,编辑时需要字段改变后才能触发
注: 这个onchange资料是网上查的,我在odoo14官方文档查了没有看到可以返回domain字典,但实际使用是可以的
文档中on_change返回的字典中可以包含两个值:
- domain字典
- warning
因为many2one存放的值是字典类型的 ,而这个domain返回回去的值就是一个字典。
@api.onchange('name')
def _onchange_name(self):
# ‘name’ many2one字段名,‘department_id’ many2one字段关联记录筛选条件字段
res = {'domain': {'name': [('department_id', 'child_of', self.department_id.id)]}}
return res
第三种:通过重写内置函数实现自定义筛选记录以及显示值名字(name_get、search、search_read)
优点:能根据字段值判断条件实现记录筛选显示,实时触发
缺点:固定筛选显示,不能分情况动态筛选
ps:nam_get函数和search或search_read函数的作用范围不一样,效果也有一定区别,建议结合起来使用
用法参考:( odoo内置函数:name_get、name_search、fields_get)详解
1. 重写name_get()
xml视图文件中,many2one字段添加context上下文
<field name="name" context="{'domain': 条件}"/>
重写many2one字段关联表py文件的name_get()函数, name_get()函数既可以实现记录筛选也可以修改显示值名字,具体可根据自己需要重写。
def name_get(self):
# 重写函数,更改many2one显示值名字和指定返回ID
result = []
context = self.env.context
if 'domain' in context.keys():
for record in self:
if 添加条件判断: # 实现返回记录筛选
name = "{}_{}".format(record.name, record.num) # 实现修改显示值名字
result.append((record.id, name))
return result
else:
# 其他情况正常返回
return super(QualityInspection, self).name_get()
作用效果:name_get是对点击下拉框时默认显示的数据做筛选,如果你点击搜索更多,name_get的筛选效果就没有了,就会调用search()函数获取数据
2. 重写search()
重写search函数或search_read函数,页面在渲染数据时会依次通过这两个函数去调用数据,因此我们可以在这里进行domain数据筛选
def search(self, args, offset=0, limit=None, order=None, count=False):
# 重写函数,返回指定记录
args = args or []
domain = []
if self.env.context.get('view_invoice_to_contract', False):
domain.extend([('state', '=', 'done'), ('invoice_id', '=', False)])
args += domain
return super(PurchaseContract, self).search(args, offset, limit, order, count)
作用效果:每当获取模块数据时都会调用相应模块的search()函数,点击搜索更多就会调用search函数,重写进行数据筛选显示
第四种:重定义视图:context="{'form_view_ref': '模块名.视图ID'}"
继承重写一个视图,然后将many2one的视图列表指向定义的视图。
<field name="name" string="员工" required="1" options="{'no_create_edit': True, 'no_open': True}" context="{'form_view_ref': '模块名.视图ID'}"/>
many2many字段和many2one字段方法类似,这里就不详细介绍。如果有其他好的方法也可以留言相互学习
相关功能实现: