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

Odoo 16 API必填字段default_value仅接受数字,输入字符报错求助

解决Odoo 16中default_value字段仅支持数字输入的问题

问题根源

输入字母或混合内容时触发NameError(如输入test报错name 'test' is not defined),因为Odoo会将default_value的内容当作Python表达式解析,而非字符串字面量。当输入无引号的字符串时,系统会把它识别为变量名,导致找不到定义报错。

解决方案

方案1:自动为字符串类型字段的默认值添加引号

在模型层处理,根据关联field_id的类型,自动给default_value添加单引号,用户无需手动输入引号:

from odoo import models, fields, api

class YourAPIFieldModel(models.Model):
    _name = 'api.field.config'  # 替换为实际模型名称
    _description = 'API Field Configuration'

    field_id = fields.Many2one('ir.model.fields', string='Field', required=True)
    default_value = fields.Char(string='Default Value')
    # 其他字段...

    @api.onchange('default_value', 'field_id')
    def _format_default_value(self):
        if self.default_value and self.field_id:
            # 定义需要当作字符串处理的字段类型
            string_field_types = ['char', 'text', 'html', 'selection']
            # 如果是字符串类型且未加引号,自动添加单引号
            if self.field_id.ttype in string_field_types and not (self.default_value.startswith("'") and self.default_value.endswith("'")):
                self.default_value = f"'{self.default_value}'"
            # 数字/布尔类型则移除多余引号(可选)
            elif self.field_id.ttype in ['integer', 'float', 'boolean']:
                self.default_value = self.default_value.strip("'\"")

    # 保存时确保格式正确
    @api.model
    def create(self, vals):
        if vals.get('field_id') and vals.get('default_value'):
            field = self.env['ir.model.fields'].browse(vals['field_id'])
            if field.ttype in ['char', 'text', 'html', 'selection'] and not (vals['default_value'].startswith("'") and vals['default_value'].endswith("'")):
                vals['default_value'] = f"'{vals['default_value']}'"
        return super().create(vals)

    def write(self, vals):
        for record in self:
            current_field = vals.get('field_id') and self.env['ir.model.fields'].browse(vals['field_id']) or record.field_id
            current_default = vals.get('default_value') or record.default_value
            if current_field.ttype in ['char', 'text', 'html', 'selection'] and not (current_default.startswith("'") and current_default.endswith("'")):
                vals['default_value'] = f"'{current_default}'"
        return super().write(vals)

方案2:在使用default_value时直接作为字符串处理

如果default_value用于API参数传递而非Odoo表达式计算,可在调用处跳过eval,直接取值:

# 原错误代码(使用eval导致报错)
# default_val = eval(record.default_value)

# 修改后的代码
if record.field_id.ttype in ['char', 'text', 'html', 'selection']:
    # 移除自动添加的引号,直接使用原始内容
    default_val = record.default_value.strip("'\"")
else:
    # 数字/布尔类型仍用eval解析
    default_val = eval(record.default_value)

效果验证

完成修改后,输入test时系统会自动转为'test',解析时被识别为字符串字面量,不再触发NameError;数字输入保持正常解析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:13:11