You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo 17中如何依据其他字段值限制单选按钮选项?

解决方案:动态限制ShipmentPackageLine的package_type选项

原代码无效原因

你之前使用的onchange方法无法生效,核心问题在于:

  • 直接修改package.fields_get()的返回值仅作用于临时对象,不会同步到前端视图的字段定义渲染。
  • fields_get()是模型级别的字段信息查询方法,针对单个记录的修改无法触发全局视图更新。

正确实现方案

方案1:通过视图属性动态控制选项可见性

直接在XML视图中,针对package_type的单选选项设置可见性规则,基于父模型freight.shipment的字段值判断:

修改freight_shipment_form_view中Package Details页面的package_type字段定义:

<form string="Package">
    <group>
        <label for="package_type"/>
        <div>
            <field name="package_type" widget="radio" options="{'horizontal':True}">
                <attribute name="attrs">
                    <attribute name="invisible">
                        <![CDATA[
                            (parent.direction == 'export' and parent.transport == 'ocean' and parent.ocean_shipment_type == 'fcl') and (value == 'item')
                        ]]>
                    </attribute>
                </attribute>
            </field>
        </div>
    </group>
    <!-- 原有其他内容 -->
</form>

该配置会在父记录满足direction='export'、transport='ocean'、ocean_shipment_type='fcl'时,自动隐藏Loose Cargo(item)选项,仅保留Containerized(container)选项。

方案2:通过模型方法动态修改字段选项

如果需要更灵活的逻辑控制,可以在ShipmentPackageLine模型中重写fields_get方法,根据关联的父记录条件动态调整package_type的可选值:

步骤1:修改ShipmentPackageLine模型

class ShipmentPackageLine(models.Model):
    _name = 'shipment.package.line'
    _rec_name = 'package'

    package_type = fields.Selection([('item', 'Loose Cargo'), ('container', 'Containerized')],
                                   string="Package Type", default='item')
    shipment_id = fields.Many2one('freight.shipment', string='Shipment', required=True)

    @api.model
    def fields_get(self, allfields=None, attributes=None):
        res = super().fields_get(allfields=allfields, attributes=attributes)
        # 遍历当前记录,根据父shipment的条件调整选项
        for record in self:
            shipment = record.shipment_id
            if shipment.direction == 'export' and shipment.transport == 'ocean' and shipment.ocean_shipment_type == 'fcl':
                res['package_type']['selection'] = [('container', 'Containerized')]
                res['package_type']['default'] = 'container'
            else:
                res['package_type']['selection'] = [('item', 'Loose Cargo'), ('container', 'Containerized')]
        return res

步骤2:完善FreightShipment的onchange方法

确保父字段变化时,同步更新子记录的字段值并触发视图刷新:

class FreightShipment(models.Model):
    _name = 'freight.shipment'

    # 原有字段定义...

    @api.onchange('direction', 'transport', 'ocean_shipment_type')
    def _onchange_shipment_conditions(self):
        if self.direction == 'export' and self.transport == 'ocean' and self.ocean_shipment_type == 'fcl':
            # 强制将现有包裹的类型设置为container
            self.freight_packages.write({'package_type': 'container'})
        # 返回空domain触发视图重新渲染,加载动态字段选项
        return {'domain': {'freight_packages': []}}

验证效果

完成上述修改后,当满足export+ocean+fcl条件时:

  • 新增或编辑包裹时,package_type仅显示Containerized选项
  • 已存在的包裹会自动切换为Containerized类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:29:56