我们在odoo中构建业务系统模块的时候,通常会使用one2many、many2one或many2many将模型进行关联,由此产生的数据也会通过外键发生关联。那么在odoo中删除数据的时候,如何关联删除呢?接下来我们以初学者的视角来观察下这一过程。

刚开始接触odoo,可能时不时的就会感叹odoo的低代码魅力:“这么少的代码,这么强悍的功能”。即便是一个主从模型的功能,很快也就完事了。正沉浸在这种喜悦中的时候,突然一个弹框提示:

目前构建的代码涉及到两个菜单功能,运单管理和承运管理,业务场景是这样的:

  • 运单管理用于创建要运送的货物的基本信息和明细信息,包括主表[waybill]和明细表[waybill_detail]
  • 承运管理也是一个主附表关系,主表[shipping_document]用来记录车辆、司机、运费等基本信息,附表[shiping_document_detail]用来记录要承运的运单信息
  • 现在要删除运单表的信息,但是提示需要把承运明细表[shiping_document_detail]中的数据删除;问题是承运管理中的数据已经删除过了,用动态图来说明下:

既然提示说需要删除承运明细表[shiping_document_detail]中的数据,在管理界面中已经删除过看不到数据了,我们不妨到数据表中看下:

原来在数据库中并没有把数据删除掉,只是把承运主表[shipping_document]的关联id删除了,如上图标记1所示。如果此时我删除运单表[waybill]中的数据,在承运明细表[shipping_document_detail]中依然有和运单相关的残留数据,如上图标记2所示。这在odoo看来是不可接受的,所以就抛出了验证错误提示。要避免这样的验证错误提示发生,我们就需要在删除承运主表[shipping_document]数据的时候,将承运明细表[shipping_document_detail]中的关联数据也删除掉。接下来我们就来说下odoo中的级联删除操作:

ondelete=’cascade’

ondelete是odoo在模型中引入的一种触发机制,在odoo16源码中,目前只有Selection和Many2one这两种字段类型支持传参调用,我们看下ondelete在Many2one类型中的定义:

通过上图我们了解到,ondelete的功能就是在参考模型中的记录被删除的时候,做一些操作。可以有’set null’、’restrict’、’cascade’这些操作,现在我们主要介绍cascade。我们在承运明细表[shipping_document_detail]的关联字段shipping_document_id上添加ondelete=’cascade’:

 1 class ShippingDocumentDetail(models.Model):
2 _name = 'shipping.document.detail'
3 _description = 'Shipping Document Detail'
4
5 waybill_id = fields.Many2one('waybill', required=True, domain="[('destination', '=', destination_id)]")
6 receiver_id = fields.Many2one(related='waybill_id.receiver_id', readonly=True)
7 receiver_tel = fields.Char(string="Consignee Phone", store=False, readonly=True, compute="_compute_customerInfo")
8 detail_ids = fields.One2many(related='waybill_id.detail_ids')
9 total_fees = fields.Float(related='waybill_id.total_fees')
10 shipping_document_id = fields.Many2one('shipping.document', string='Shipping Document',ondelete='cascade')
11 destination_id=fields.Integer(string='Destination Id', compute="_compute_destination_id")

模块升级后,我们先手动删除承运明细表[shipping_document_detail]中的残留数据,然后添加新的测试数据,我们添加的承运单截图如下:

数据库中对应截图如下:

接下来我们执行承运单的删除操作,再查询数据库的时候,发现刚才创建的数据已经没有了。

写这篇博客的时候,我已经整理好了文章大纲,边写边测试验证,最后发现我原来的理解是错的,原来的大纲中还有在One2many中使用ondelete=’cascade’,以及ondelete=’cascade’无法解决问题时如何通过unlink()来解决。唉,半路借来的内容真是害人不轻。还好写了博客,又参考odoo官方文档和源码走了一遍流程;不仅深入的理解了这个知识点,也优化了一知半解的时候写的代码。

源码地址【源码更新会有3-5天的时间出入】:github

点击链接阅读原文:菜园工程师

Odoo16—级联删除的更多相关文章

  1. [原创]MYSQL中利用外键实现级联删除和更新

    MySQL中利用外键实现级联删除.更新 MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定 ...

  2. EF里一对一、一对多、多对多关系的配置和级联删除

    本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个PersonPhoto类,表示用户照片类 /// < ...

  3. EF级联删除

    引言     在主表中指定Key,子表中指定Required后,并不会在数据库中生成级联删除的外键.那怎么才能使EF在数据中生成级联删除的外键? SQLServer数据库中级联删除功能配置界面: 上图 ...

  4. [NHibernate]一对多关系(级联删除,级联添加)

    目录 写在前面 文档与系列文章 一对多关系 一个例子 级联删除 级联保存 总结 写在前面 在前面的文章中,我们只使用了一个Customer类进行举例,而在客户.订单.产品中它们的关系,咱们并没有涉及, ...

  5. SQLServer表内自关联级联删除

    今天处理SQLServer级联删除遇到了很蛋疼的事. SQLServer 不支持表内自关联级联删除,而MySql和Oracle却支持. 貌似原因是SQLServer 会产生循环级联,就不给这样弄.所以 ...

  6. Entity framework 级联删除注意事项

    版本:EF6.0.1 RC 一对多场景,在子对象映射中开启级联删除情况下,删除父对象将自动删除其下所有子对象,需要注意一些事项: 需要保证DbContext中已经加载了该父对象的所有子对象. 如果Db ...

  7. Oracle 级联删除

    alter table ForeignTable(附表)add constraint fk_MainTable_ForeignTable(关联表中的外键) foreign key(ForeignTab ...

  8. MySQL级联删除的问题

    一.FOREIGN KEY 的定义分为两种:列级约束和表级约束 .列及约束的话,可以在列定义的同时,定义外键约束.比如 如果有2张表,主表:T1(A1 )) 要在从表T2中定义外键列这可以: Crea ...

  9. EntityFramework SQLiteCodeFirst 自动创建数据库 关闭级联删除

    外键的级联删除: 如A表中有主键idA, B表中设置外键(ForeignKey)为A表中的主键idA, 当A表中的记录被删除时, B表中所有引用此条记录的记录(即所有外键为idA的记录)将自动被删除 ...

  10. SQL级联删除——删除主表同时删除从表——同时删除具有主外键关系的表

    create table a(id  varchar(20) primary key,password varchar(20) not null) create table b(id int iden ...

随机推荐

  1. Llama2-Chinese项目:3.1-全量参数微调

      提供LoRA微调和全量参数微调代码,训练数据为data/train_sft.csv,验证数据为data/dev_sft.csv,数据格式如下所示: "<s>Human: &q ...

  2. Django框架——模板层

    文章目录 1 模板层 一 模版简介 二 模版语法之变量 views.py html文件 三 模版之过滤器 语法: default length filesizeformat date slice tr ...

  3. Python基础——二分法、面向过程编程思想、有名函数、lambda、max、_min的应用、sorted排序、map的应用、filter的应用、reduce的应用

    文章目录 内容回顾 二分法 伪代码模板 面向过程编程思想 函数式 def用于定义有名函数 lambda用于定义匿名函数 调用匿名函数 匿名函数作用 匿名函数的示范 max的应用 min的应用 sort ...

  4. Spring Boot中发送邮件时,如何让发件人显示别名

    之前,我们通过一系列文章,介绍了如何在Spring Boot中发送邮件: 发送邮件 添加附件 引用静态资源 邮件模版 已经包含了大部分的应用场景.但最近DD在做YouTube中文配音的时候,碰到一个问 ...

  5. DELL R750

    两种情况不常见 1.如果R750的配置单里提到 跳线-C13/C14.0.6M.250V.10A(中国.韩国)   要注意里面写的0.6M,表示这个线是0.6米的,较短,客户机房环境复杂的情况下,很可 ...

  6. 文心一言 VS 讯飞星火 VS chatgpt (113)-- 算法导论10.2 5题

    五.用go语言,使用单向循环链表实现字典操作 INSERT.DELETE 和 SEARCH,并给出所写过程的运行时间. 文心一言: 在Go语言中,我们首先需要定义一个Node结构体来表示单向循环链表的 ...

  7. 使用Blazor构建投资回报计算器

    本文由葡萄城技术团队原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 本博客中创建的投资计算器根据存入金额和回报率计算每个投资周期的特定回报 ...

  8. 自定义过滤器配置 Shiro 认证失败返回 json 数据

    by emanjusaka from ​ https://www.emanjusaka.top/archives/11 彼岸花开可奈何 本文欢迎分享与聚合,全文转载请留下原文地址. Shiro权限框架 ...

  9. 解决使用mitmprox抓包可以访问网页,但是使用python request 调用该网站接口报错问题

    可能有几种原因导致这种情况.以下是一些常见的问题和可能的解决方法: 证书验证问题: 当你使用mitmproxy抓包时,它通常会生成自签名的SSL证书,以便进行中间人攻击检查.但在Python中使用re ...

  10. ubuntu20.04不定时卡死,鼠标和键盘都不可用,且tty无效

    事情的经过: 已经在ubuntu上安装了好多东西,配置了好多环境,最近突然莫名卡死.我遇到的问题是: 1.如果开机之后只是打开终端,打开编辑器之类的操作,系统不会卡死. 2.一旦打开firefox火狐 ...