Odoo 自定义过滤功能
Odoo Custom filter function
我已经尝试了所有方法并到处搜索答案,但没有成功。
我想实现一个自定义函数来检索 Many2one selection 列表的过滤值。
通常你会为此使用域,但给出的域选项不足以实现我的目标。
我必须覆盖什么函数才能修改给定 Many2one 字段的 selection 列表?
谢谢,
拉斯
更新:
感谢您的回答。我使用 name_search
来分析生成的 WHERE 子句。
这是我想要实现的目标和我目前的发现:
programs = fields.Many2many(
comodel_name='hr.program',
relation='hr_process_onboarding_wizard_programs')
program_department = fields.Many2one(
comodel_name='hr.department',
domain="[('programs', 'in', programs)]")
字段程序表示为many2many_checkboxes小部件。
当我 select 2 个值时,以下域过滤器将传递给 name_search
:['programs', 'in', [1, 2]]
这将生成以下 SQL-Query(有趣部分的摘录):(SELECT "hr_department_id" FROM "hr_programs_departments" WHERE "hr_program_id" IN (1,2))
结果列表当然是程序 [1,2] 的 UNION,但我希望程序 [1,2] 是 INTERSECTION。
Afaik 没有域过滤器来获取交集。
更新 2:
在考虑了给定的过滤器运算符之后,我希望 =
完全按照我的意愿进行操作,但是运算符 =
生成与 in
.[=18 相同的 WHERE 子句=]
我想我们在同一页上,我想建议 _search 方法,因为每次当你点击 many2one 字段时,这个 _search 方法与您在 py 中写入的域或 xml.
您可以覆盖它并发挥作用。
无论何时重写此类方法,您都需要注意一件事。
我建议你从你的领域传递上下文和 _search 方法中的一个条件(在所有代码之上)这样你的代码就不会影响到其他地方,因为使用了 _search 方法无处不在。
谢谢
这是我在 class HrDepartment
中使用 name_search
的快速破解解决方案。
我在相应视图的字段中添加了一个属性 context="{'intersect': True}"
,以便在其他上下文中实现故障保护。
domain
仍然存在并在 must_contain_programs
中使用。
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
is_intersect_context = self._context.get('intersect')
must_contain_programs = args[0][2]
if(is_intersect_context and len(must_contain_programs) > 1):
all_departments = self.env['hr.department'].search([])
filtered_departments = []
for department in all_departments:
if all(program_id in department.programs.ids for program_id in must_contain_programs):
filtered_departments.append(department)
if len(filtered_departments) > 0:
intersect_res = []
for filtered_department in filtered_departments:
intersect_res.append((filtered_department.id, filtered_department.name))
intersect_res.sort(key=lambda tuple: tuple[0])
if name != '':
res = list(filter(lambda tuple: name.upper() in tuple[1].upper(), intersect_res))
else:
res = intersect_res
else:
res = super(HrDepartment, self).name_search(name, args, operator, limit)
return res
我已经尝试了所有方法并到处搜索答案,但没有成功。
我想实现一个自定义函数来检索 Many2one selection 列表的过滤值。 通常你会为此使用域,但给出的域选项不足以实现我的目标。
我必须覆盖什么函数才能修改给定 Many2one 字段的 selection 列表?
谢谢, 拉斯
更新:
感谢您的回答。我使用 name_search
来分析生成的 WHERE 子句。
这是我想要实现的目标和我目前的发现:
programs = fields.Many2many(
comodel_name='hr.program',
relation='hr_process_onboarding_wizard_programs')
program_department = fields.Many2one(
comodel_name='hr.department',
domain="[('programs', 'in', programs)]")
字段程序表示为many2many_checkboxes小部件。
当我 select 2 个值时,以下域过滤器将传递给 name_search
:['programs', 'in', [1, 2]]
这将生成以下 SQL-Query(有趣部分的摘录):(SELECT "hr_department_id" FROM "hr_programs_departments" WHERE "hr_program_id" IN (1,2))
结果列表当然是程序 [1,2] 的 UNION,但我希望程序 [1,2] 是 INTERSECTION。
Afaik 没有域过滤器来获取交集。
更新 2:
在考虑了给定的过滤器运算符之后,我希望 =
完全按照我的意愿进行操作,但是运算符 =
生成与 in
.[=18 相同的 WHERE 子句=]
我想我们在同一页上,我想建议 _search 方法,因为每次当你点击 many2one 字段时,这个 _search 方法与您在 py 中写入的域或 xml.
您可以覆盖它并发挥作用。
无论何时重写此类方法,您都需要注意一件事。 我建议你从你的领域传递上下文和 _search 方法中的一个条件(在所有代码之上)这样你的代码就不会影响到其他地方,因为使用了 _search 方法无处不在。
谢谢
这是我在 class HrDepartment
中使用 name_search
的快速破解解决方案。
我在相应视图的字段中添加了一个属性 context="{'intersect': True}"
,以便在其他上下文中实现故障保护。
domain
仍然存在并在 must_contain_programs
中使用。
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
is_intersect_context = self._context.get('intersect')
must_contain_programs = args[0][2]
if(is_intersect_context and len(must_contain_programs) > 1):
all_departments = self.env['hr.department'].search([])
filtered_departments = []
for department in all_departments:
if all(program_id in department.programs.ids for program_id in must_contain_programs):
filtered_departments.append(department)
if len(filtered_departments) > 0:
intersect_res = []
for filtered_department in filtered_departments:
intersect_res.append((filtered_department.id, filtered_department.name))
intersect_res.sort(key=lambda tuple: tuple[0])
if name != '':
res = list(filter(lambda tuple: name.upper() in tuple[1].upper(), intersect_res))
else:
res = intersect_res
else:
res = super(HrDepartment, self).name_search(name, args, operator, limit)
return res