跳至内容

Odoo 中 Many2one 字段 ondelete 属性详解:删除关联记录的三种策略

 在 Odoo 模型设计中,Many2one字段用于建立表间的关联关系,而ondelete属性则决定了当被关联记录(主记录)被删除时,当前记录(关联记录)的处理方式。通过具体模型示例,详解ondelete的三种常见策略:restrict、set null和cascade,帮助开发者根据业务需求选择合适的关联删除逻辑。

一、模型示例:项目与明细行的关联

我们以两个模型为例:

项目主表(edoproject.project):通过One2many字段关联多个明细行

项目明细行表(edoproject.projectmx):通过Many2one字段关联主项目,并设置ondelete策略


项目主表

class EdoProject_Project(models.Model):

    _name = "edoproject.project"

    _description = "项目档案"

   

    projectmx_ids = fields.One2many(

        'edoproject.projectmx',  # 关联的明细行模型

        'pinban_id',             # 明细行中的外键字段(即projectmx模型中的反向关联字段)

        string='明细记录'

    )


项目明细行表

class EdoProject_Projectmx(models.Model):

    _name = "edoproject.projectmx"

    _description = '项目明细行'

   

    project_id = fields.Many2one( 

​ ​ 'edoproject.project',    # 关联的主项目模型

        string='项目ID',

        ondelete="restrict"      # 重点:设置删除策略

    )


二、ondelete 策略详解

1. ondelete="restrict"(默认策略,限制删除)

效果:当主项目记录(edoproject.project)存在关联的明细行时,禁止删除主记录。

Odoo 会抛出错误提示:Cannot delete record because it is referenced by other records,并阻止删除操作。

适用场景:

当需要严格保证数据完整性,不允许删除仍有依赖记录的主数据时使用(例如:禁止删除仍有订单的客户)。


代码示例:

project_id = fields.Many2one('edoproject.project', string='项目ID', ondelete="restrict")


操作演示:

若主项目存在projectmx_ids明细行,直接删除主项目会触发 Odoo 的完整性校验,操作失败。


2. ondelete="set null"(置空外键)

效果:删除主项目时,自动将所有关联的明细行的project_id字段设置为NULL(空值)。

需注意:明细行的project_id字段必须允许NULL(即required=False,默认允许),否则会报错。

适用场景:

当允许明细行在主项目删除后独立存在(如历史记录归档),但需断开关联关系时使用。


代码示例:

project_id = fields.Many2one('edoproject.project', string='项目ID', ondelete="set null")


操作演示:

删除主项目后,查询明细行表会发现project_id字段值变为NULL,明细行仍保留在数据库中。


3. ondelete="cascade"(级联删除)

效果:删除主项目时,自动级联删除所有关联的明细行记录。

这是最 “激进” 的策略,主记录与关联记录会被同时删除。

适用场景:

当关联记录完全依赖主记录存在(如订单与订单项),主记录删除时关联数据失去意义时使用。


代码示例:

project_id = fields.Many2one('edoproject.project', string='项目ID', ondelete="cascade")


操作演示:

删除主项目后,对应的projectmx_ids明细行会被自动删除,数据库中不再存在相关记录。


三、注意事项

默认策略:若不显式设置ondelete,Odoo 默认使用restrict策略,确保数据不被意外删除。

字段约束:使用set null时,需确保Many2one字段允许NULL(即未设置required=True),否则 Odoo 会因无法置空而报错。


业务逻辑一致性

选择策略时需结合业务规则,例如:

财务系统中,禁止删除有凭证的科目(用restrict);

日志系统中,允许日志在来源删除后保留(用set null);

订单系统中,订单删除时同步删除订单项(用cascade)。

博客
ODOO是什么