Odoo14动作服务器错误:无法正确调用Python方法
Odoo14 服务器动作调用窗口动作报错解决
问题定位
从报错栈和代码来看,核心问题集中在以下几点:
- 日期处理逻辑错误:Odoo的
date字段本身是datetime.date类型,代码里用datetime.strptime(self.date, '%Y-%m-%d')试图将日期对象转字符串再解析,触发类型错误进而引发断言失败。 - 上下文覆盖问题:直接替换
action['context']会丢失原动作的默认上下文,可能引发后续逻辑异常。 - 记录集处理缺失:方法未处理多记录场景,通过
model调用或选中多条记录时,访问self.payment_ref这类字段会报错。 - XML调用对象错误:原XML中用
model调用方法,model是模型类对象而非具体记录,应该用record指代当前选中的单条记录。
修正后的代码
1. Python 方法修正
from datetime import datetime def action_payment_bank_statement_line(self): # 强制方法仅处理单条记录,避免多记录访问字段报错 self.ensure_one() action_ref = 'account.view_account_payment_form' action = self.env['ir.actions.act_window']._for_xml_id(action_ref) # 合并原有上下文与自定义默认值,保留原动作上下文配置 action['context'] = dict( action.get('context', {}), default_payment_type='outbound', default_partner_type='customer', default_ref=self.payment_ref or '', default_amount=self.amount or 0.0, default_date=self.date # 直接使用Odoo原生date字段值 ) action['view_mode'] = 'form' action['target'] = 'new' return action
2. XML 服务器动作修正
<field name="name">Créer un paiement</field> <field name="model_id" ref="account.model_account_bank_statement_line"/> <field name="binding_model_id" ref="account.model_account_bank_statement_line"/> <field name="state">code</field> <field name="binding_view_types">list</field> <!-- 使用record调用方法,指向当前选中的单条记录 --> <field name="code">action = record.action_payment_bank_statement_line()</field>
关键修改说明
ensure_one():确保方法仅处理单条记录,避免多记录场景下访问字段引发的错误。- 日期字段直接使用:Odoo的
date字段存储为datetime.date对象,无需额外解析,直接赋值即可。 - 上下文合并方式:用
dict()合并原有上下文和自定义默认值,保留原动作的上下文配置(如用户语言、公司信息等)。 - XML中使用
record:列表视图的服务器动作中,record指代当前选中的单条记录,确保方法能访问到具体记录的字段值。
替代方案(无需服务器动作,直接用窗口动作)
如果不需要额外Python逻辑,也可以直接定义窗口动作,通过上下文传递字段值:
<record id="action_create_payment_from_statement_line" model="ir.actions.act_window"> <field name="name">Créer un paiement</field> <field name="res_model">account.payment</field> <field name="view_mode">form</field> <field name="target">new</field> <field name="context">{ 'default_payment_type': 'outbound', 'default_partner_type': 'customer', 'default_ref': active_id.payment_ref, 'default_amount': active_id.amount, 'default_date': active_id.date }</field> </record> <!-- 绑定到account.bank.statement_line的列表视图 --> <record id="bank_statement_line_payment_action_binding" model="ir.actions.act_window.view"> <field name="act_window_id" ref="action_create_payment_from_statement_line"/> <field name="view_id" ref="account.view_account_bank_statement_line_tree"/> </record>
内容的提问来源于stack exchange,提问作者Ka_
相关产品推荐
相关产品推荐

