在odoo中,我有2个字段:state_id和district_id。本质上,我想选择一个州,那么在选择一个地区时,它只会显示属于该州的地区。我通常这样做: t 将创建一个虚拟字段
domain_district = fields.Char(compute='_compute_domain_district')
并计算该字段,该字段将存储您需要显示的学区学校的ID
@api.depends('state_id')
def _compute_domain_district(self):
for rec in self:
if rec.state_id:
districts = self.env['res.country.district'].sudo().search([('state_id', '=', rec.state_id.id)])
domain = [('id', 'in', districts.ids)] if districts else []
else:
domain = []
rec.domain_district = json.dumps(domain)
在 xml 里面只需要
<field name="district_id" placeholder="District" domain="domain_district"
nolabel="1"/>
这个方法效果很好,但我发现它又长又复杂,因为我必须创建额外的计算字段,所以我想要一个比使用 onchange 函数更简单的方法,我做了以下操作:
@api.onchange('state_id', 'district_id')
def _onchange_state_id(self):
result = {}
if self.state_id:
result['domain'] = {'district_id': [('state_id', '=', self.state_id.id)]}
else:
result['domain'] = {'district_id': [('id', 'in', [])]}
return result
但是这个函数似乎不正确,即使我选择了state_id,在选择district_id时,它并没有过滤掉正确的记录,它仍然显示所有district_id,我需要你的帮助来解决这个问题。这个?
我认为这不是在 Odoo 17 中使用 @api.onchange 的正确方法。当您临时修改表单上的字段时(即保存/恢复按钮出现在顶部),活动记录将被复制到临时记录中记录。 @api.onchange 可以在其依赖项改变时修改此临时记录,但它不能直接影响字段的域。
您要做的是修改district_id的域名。
您可以在表单视图的 Many2one 字段中设置域。如果您自己定义了表单视图,只需向
<field name="district_id" domain=... />
添加一个域即可。否则,如果它是一个已经定义的视图,则必须使用 xpath。如果你用谷歌搜索,会有很多指南解释如何做到这一点。
或者,由于您设置了 @api.onchange,我假设您继承了您想要影响的表单的模型(如果您没有,请提供更多代码,以便人们可以复制/分析问题)。如果是这种情况,您只需从任意模型复制
district_id = fields...
定义并向其添加域即可。如果您不确定如何操作,请查看源代码中的任何帐户模型,它在那里使用得相当广泛。
如果您不想覆盖 District_id 中的任何预定义域,最后的办法是定义您自己的自定义 Many2One 小部件(如果您可以执行 Javascript)。如果您查看“web”模块,在“static/src/views/fields/many2one”下有一个可以扩展的 Many2OneField 组件。该组件有一个
get domain()
函数,您可以覆盖该函数以更改传递到视图中 Many2one 字段的域。默认情况下,返回的域是表单或模型中定义的任何域。通过覆盖该函数并使用“web/core/domain”中的 Domain 类,您可以动态向其添加域。