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

点击保存按钮时,Odoo的create和write方法如何触发?

嘿,我来给你拆解一下Odoo里点击保存按钮时create和write方法的执行逻辑,结合你贴的模型代码来讲会更清楚~

Odoo保存按钮触发的create/write方法执行流程

Odoo的保存按钮其实对应两种场景:新建记录和编辑已有记录,分别触发create和write方法,逻辑略有不同,下面分开说:

1. 新建记录时的create方法执行流程

当你在空白表单里填完所有必填字段(比如你模型里的name、code、key_letter这些),点击保存的那一刻:

  • 前端会把你填写的所有字段数据打包成JSON,发送给Odoo后端的Web控制器;
  • 后端会定位到你对应的health_administrator.medical_procedure_base模型,调用它的create方法;
  • 默认的create方法(继承自models.Model)会按顺序做这些事:
    • 先验证字段约束:比如检查所有required=True的字段有没有填,没填直接抛错误,前端会弹出提示阻止创建;
    • 处理关联字段:比如你的key_letter是Many2one,Odoo会自动验证你选的关联记录是否存在,确保外键关联合法;
    • 把处理好的数据写入数据库对应的表(Odoo会自动生成表名health_administrator_medical_procedure_base);
    • 触发一系列ORM钩子:比如字段的compute方法(如果有的话)、模型上的@api.model_create_multi装饰器逻辑等;
    • 最后把新建记录的ID返回给前端,页面跳转到这条记录的详情页。

2. 编辑已有记录时的write方法执行流程

当你打开一条已有的记录,修改部分字段后点击保存:

  • 前端只会把你修改过的字段加上这条记录的ID打包发送给后端(不会传所有字段,节省资源);
  • 后端调用模型的write方法;
  • 默认的write方法会做这些事:
    • 先检查权限:确保当前用户有修改这条记录的权限;
    • 验证字段约束:比如如果把name清空了,会触发必填校验报错;
    • 处理关联字段更新:比如你换了medical_procedure_cat_id,Odoo会更新对应的外键值,同时处理反向关联的逻辑;
    • 只更新数据库中变化的字段(不是全量更新);
    • 触发ORM钩子:比如字段的compute方法、模型上的@api.multi装饰器逻辑等;
    • 返回成功状态给前端,页面刷新显示修改后的内容。

结合你的模型代码的具体例子

你的模型定义了几个核心必填字段,举个实际场景:

class medical_procedure_base(models.Model):
    _name = 'health_administrator.medical_procedure_base'
    _description = 'Medical Procedure'
    name = fields.Char(string='标签', required=True)
    code = fields.Char(string='编码', required=True)
    key_letter = fields.Many2one('health_administrator.key_letter', required=True, string="关键字母")
    medical_procedure_cat_id = fields.Many2one('health_administrator.medical_procedure_category', required=True, string="操作类别")
    # 你代码里的amoun...应该是金额字段,假设是amount = fields.Float(string='金额')
  • 新建时:如果key_letter没选,点击保存会直接弹出“关键字母是必填项”的提示,create方法不会执行数据库写入;
  • 编辑时:如果你只修改了name,write方法只会更新数据库里这条记录的name字段,其他字段保持不变。

自定义create/write方法的小提示

如果你想在保存时加自己的逻辑(比如自动生成编码、记录修改日志),可以重写这两个方法,但一定要记得调用父类的方法,不然默认的校验、字段处理逻辑会丢失:

from odoo import models, fields, api

class medical_procedure_base(models.Model):
    # 你的模型定义...

    @api.model
    def create(self, vals):
        # 自定义逻辑:自动生成编码
        vals['code'] = self.env['ir.sequence'].next_by_code('medical.procedure.code') or 'DEFAULT_CODE'
        # 必须调用父类的create方法,否则默认逻辑失效
        return super(medical_procedure_base, self).create(vals)

    def write(self, vals):
        # 自定义逻辑:修改编码时记录日志
        if 'code' in vals:
            self.env['medical.procedure.log'].create({
                'procedure_id': self.id,
                'old_code': self.code,
                'new_code': vals['code'],
                'change_date': fields.Date.today()
            })
        # 必须调用父类的write方法
        return super(medical_procedure_base, self).write(vals)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:48:20