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

动态计算值的Selection字段无法正常工作问题咨询

解决Odoo动态计算Selection字段失效的问题

看起来你在尝试创建一个基于上下文动态生成选项的Selection字段,但遇到了功能异常的情况。我来帮你拆解问题并给出修复方案:

核心问题分析

Odoo中,fields.Selection支持通过方法动态返回选项列表,但你的实现存在几个关键问题:

  • 代码片段截断,方法没有返回完整的选项元组列表
  • 未处理active_ids/active_model为空的边界场景(比如新建记录时,上下文没有传递这些值)
  • 可能没有正确处理多记录批量选择的情况

修复步骤

1. 完善动态选项生成方法

首先补全_compute_selection方法,确保它返回标准的Selection格式([(值, 标签), ...]),同时处理各种边界情况:

# 先定义发票类型到伙伴类型的映射(根据你的业务需求调整)
MAP_INVOICE_TYPE_PARTNER_TYPE = {
    'out_invoice': 'customer',
    'in_invoice': 'supplier',
    'out_refund': 'customer',
    'in_refund': 'supplier',
}

# 定义不同伙伴类型对应的付款方式选项
PAYMENT_MODES = {
    'customer': [('cash', 'Cash'), ('card', 'Credit Card'), ('bank_transfer', 'Bank Transfer')],
    'supplier': [('cash', 'Cash'), ('bank_transfer', 'Bank Transfer'), ('check', 'Check')],
}

@api.model
def _compute_selection(self):
    context = dict(self._context or {})
    active_ids = context.get('active_ids')
    active_model = context.get('active_model')
    
    # 默认返回基础选项,避免无上下文时出错
    default_options = [('cash', 'Cash')]
    
    # 校验上下文有效性
    if not active_ids or active_model != 'account.move':
        return default_options
    
    # 获取关联的发票记录
    invoices = self.env[active_model].browse(active_ids)
    if not invoices:
        return default_options
    
    # 处理批量选择的情况:取第一个发票的类型,或者统一校验所有发票类型一致
    invoice_type = invoices[0].type
    partner_type = MAP_INVOICE_TYPE_PARTNER_TYPE.get(invoice_type)
    
    # 返回对应类型的付款选项,没有匹配则返回默认
    return PAYMENT_MODES.get(partner_type, default_options)

2. 确保字段声明正确

你的字段声明写法是对的,但要注意Odoo版本兼容性(比如新版本中发票模型是account.move而非旧版的account.invoice):

payment_mode = fields.Selection(
    selection='_compute_selection',
    string="Payment mode",
    default="cash"
)

注意:这里显式写selection='_compute_selection'比直接传方法名更清晰,避免歧义。

3. 排查上下文传递问题

如果字段是在弹窗(比如从发票列表打开的 wizard)中使用,要确保弹窗的上下文正确传递了active_ids和active_model。在视图的按钮定义中要加上context="{'active_ids': active_ids, 'active_model': active_model}":

<button name="%(your_wizard_action_id)d" string="Create Payment" type="action" context="{'active_ids': active_ids, 'active_model': active_model}"/>

4. 进阶:实时动态更新选项(可选)

如果需要在表单编辑时,随着关联发票的变化实时更新付款方式选项,Selection字段的静态特性可能无法满足需求。推荐改用Many2one字段配合动态domain:

# 替换原Selection字段为Many2one
payment_mode_id = fields.Many2one(
    'account.payment.mode',
    string="Payment mode",
    domain="[('partner_type', '=', _get_partner_type)]"
)

@api.model
def _get_partner_type(self):
    # 复用之前的逻辑获取伙伴类型
    context = dict(self._context or {})
    active_ids = context.get('active_ids')
    active_model = context.get('active_model')
    if active_ids and active_model == 'account.move':
        invoice = self.env[active_model].browse(active_ids)[0]
        return MAP_INVOICE_TYPE_PARTNER_TYPE.get(invoice.type)
    return 'customer'

这种方式能更灵活地实现动态选项过滤,且符合Odoo的最佳实践。

常见排查点

  • 检查active_model是否为当前Odoo版本的正确模型名(比如v13+用account.move,旧版用account.invoice)
  • 确保当前用户有权限访问active_model对应的记录(否则browse(active_ids)会返回空记录集)
  • 测试单个记录和批量记录场景,确保逻辑都能覆盖

内容的提问来源于stack exchange,提问作者Marek Jan-Alexander

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:51:08