You need to enable JavaScript to run this app. Odoo计算字段设置store=True后存储值为0且需加入自定义过滤的问题
优惠活动
大模型
产品
解决方案
定价
更多

Odoo计算字段设置store=True后存储值为0且需加入自定义过滤的问题

核心问题根因
  • 带存储的compute字段必须配置依赖触发规则:Odoo中store=True的compute字段,必须通过@api.depends明确指定哪些字段变化时需要重算,否则仅会在记录创建时执行一次计算。你当前的逻辑里,刚创建楼宇时还没有绑定任何客户,算出来的客户数是0,后续不管绑定了多少客户,因为没有配置依赖,永远不会触发重算,数据库里的值就一直停留在初始的0。
  • 字段类型不匹配:customer_count被定义为Char类型存储整数计数,既不符合语义,也会导致筛选时的数值比较逻辑异常。
  • 重复定义方法导致逻辑失效:模型中写了两个同名的write方法,Python的类属性覆盖规则会让后定义的write完全覆盖前一个,之前写的区域、城市同步给客户的逻辑根本不会被执行。
  • 原生SQL绕过ORM机制:直接拼接SQL字符串更新关联客户表的数据,既存在SQL注入风险,也不会触发Odoo的compute字段重算流程。
  • 不带store的字段无法参与筛选:不设置store=True的compute字段是界面加载时实时计算,不会存储到数据库,筛选逻辑需要在数据库层执行SQL查询,没有落库的字段自然不会出现在可筛选的字段列表里。
修复步骤
  1. 重构customer_count字段定义与计算逻辑
    把字段类型改为整数,为compute方法添加正确的依赖声明,让关联客户变化时自动触发重算:
    # 字段定义
    customer_count = fields.Integer(
        string='Customer Count',
        compute='_compute_customer_count',
        store=True  # 落库后即可支持自定义筛选
    )
    
    # 计算方法
    @api.depends('partner_ids')  # 关联的客户列表变化时自动重算
    def _compute_customer_count(self):
        for record in self:
            # 直接统计关联客户的数量,比单独写search_count效率更高
            record.customer_count = len(record.partner_ids)
    
  2. 合并重复的write方法逻辑
    去掉重复的方法定义,把两个write里的业务逻辑合并到同一个方法中,改用ORM接口更新关联客户数据,避免原生SQL的风险:
    def write(self, vals):
        # 先执行原有的write逻辑
        res = super(ResBuilding, self).write(vals)
        # 楼宇所属覆盖区域变化时,同步更新关联客户的居住区域
        if vals.get('city_id'):
            related_partners = self.env['res.partner'].search([('building_id', 'in', self.ids)])
            related_partners.write({'living_area': vals['city_id']})
        # 楼宇所属行政区变化时,同步更新关联客户的所属区域
        if vals.get('region_id'):
            related_partners = self.env['res.partner'].search([('building_id', 'in', self.ids)])
            related_partners.write({'city_id': vals['region_id']})
        return res
    
  3. 优化位置坐标同步的SQL逻辑
    修正原有拼接SQL的写法,改用参数化查询避免SQL注入:
    @api.depends('latitude', 'longitude')
    def on_change_location(self):
        for record in self:
            if record.latitude and record.longitude:
                # 参数化查询,不要直接拼接字符串
                self.env.cr.execute(
                    """
                    UPDATE res_partner 
                    SET location_latitude = %s, location_longitude = %s 
                    WHERE building_id = %s
                    """,
                    (record.latitude, record.longitude, record.id)
                )
    
  4. 视图侧调整
    表单视图里的customer_count字段的force_save="1"属性可以去掉,字段本身已经落库,不需要强制保存即可参与筛选。
效果验证
  • 新建楼宇绑定客户后,customer_count会自动更新为实际关联的客户数量,不会停留在0值
  • 历史存量楼宇数据在模块升级时,会自动触发一次compute重算,把数据库里存储的0值修正为正确的统计结果
  • customer_count会正常出现在列表视图的自定义筛选可选字段列表中,支持按数值范围做过滤

内容的提问来源于stack exchange,提问作者Shahal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 17:45:03