GeekTop
  • 首页
  • 关于

GeekTop

不止代码

修复 Odoo 的一个 bug

修复 Odoo 的一个 bug

2019年1月8日 Alex Comments 0 Comment

在使用 Odoo 的时候,发现 Odoo 的一个 bug,这里贴出来。

先来看一段odoo的代码(addons/product/models/product.py):

@api.multi
def unlink(self):
    unlink_products = self.env['product.product']
    unlink_templates = self.env['product.template']
    for product in self:
        # Check if product still exists, in case it has been unlinked by unlinking its template
        if not product.exists():
            continue
        # Check if the product is last product of this template...
        other_products = self.search([('product_tmpl_id', '=', product.product_tmpl_id.id), ('id', '!=', product.id)])
        # ... and do not delete product template if it's configured to be created "on demand"
        if not other_products and not product.product_tmpl_id.has_dynamic_attributes():
            unlink_templates |= product.product_tmpl_id
        unlink_products |= product
    res = super(ProductProduct, unlink_products).unlink()
    # delete templates after calling super, as deleting template could lead to deleting
    # products due to ondelete='cascade'
    unlink_templates.unlink()
    return res

这段代码的作用是在删除商品的时候,去检查商品模板,如果商品模板没有关联的其它商品,那么就把商品模板一起删掉,正常情况下,这是没有问题的。

但是,这里有考虑不周到的地方,如果一个产品有多个变体,当其中的一个变体已经归档的话,other_products = self.search([('product_tmpl_id', '=', product.product_tmpl_id.id), ('id', '!=', product.id)]) 这条语句是查不出来已经归档的变体的,从而导致在删除 templates 造成数据库约束错误。

正确的做法如下所示:

@api.multi
def unlink(self):
    unlink_products = self.env['product.product']
    unlink_templates = self.env['product.template']
    for product in self:
        # Check if product still exists, in case it has been unlinked by unlinking its template
        if not product.exists():
            continue
        # Check if the product is last product of this template...
        other_products = self.search([('product_tmpl_id', '=', product.product_tmpl_id.id), ('id', '!=', product.id), \
                                '|', ('active', '=', False), ('active', '=', True)])
        # ... and do not delete product template if it's configured to be created "on demand"
        if not other_products and not product.product_tmpl_id.has_dynamic_attributes():
            unlink_templates |= product.product_tmpl_id
        unlink_products |= product
    res = super(ProductProduct, unlink_products).unlink()
    # delete templates after calling super, as deleting template could lead to deleting
    # products due to ondelete='cascade'
    unlink_templates.unlink()
    return res

遵循最小改动原则,只需要把查询搞成 other_products = self.search([('product_tmpl_id', '=', product.product_tmpl_id.id), ('id', '!=', product.id), '|', ('active', '=', False), ('active', '=', True)]) 即可。

向 Odoo 官方提交了一个 : PR

后来,还有一种更好的做法:

other_products = self.env['product.product'].with_context(active_test=False).\
                                    search([('product_tmpl_id', '=', product.product_tmpl_id.id), ('id', 'not in', self.ids)])

这种写法看起来更好。


时间线

发布日期:2018-12-25

最后修改日期:2019-03-14


Odoo

Post navigation

NEXT
数据库的主键策略
PREVIOUS
我的 2018

发表回复 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

最近文章

  • 姥姥
  • 设计一个可扩展的用户模型
  • 使用 Apple 的 Keychain 保存 SSH 的 passphase
  • 解决 ABA 问题
  • 关于 macOS 上面部分 emoji 无法显示的问题
  • 这些年我技术栈的变化
  • 搬瓦工、狗云、hostodo、oracle对比测试
  • Google Drive 无法上传文件
  • 使用 socks5 代理 git ssh 协议
  • 到底要不要“润”
  • 可复用的代码
  • 关于疫情的一点点反思
  • 我的风控策略(投资篇)
  • 我的风控策略(生活篇)
  • Spring Boot是如何处理异常的
  • 编码与解码
  • 基于统计的图像目标检索
  • 有限状态机和状态模式
  • API安全设计
  • 用户密码的存储策略

近期评论

  • ǝɔɐǝԀʎzɐɹϽ发表在《可复用的代码》
  • Alex发表在《可复用的代码》
  • ǝɔɐǝԀʎzɐɹϽ发表在《到底要不要“润”》
  • ǝɔɐǝԀʎzɐɹϽ发表在《可复用的代码》
  • ǝɔɐǝԀʎzɐɹϽ发表在《我的风控策略(生活篇)》
  • ǝɔɐǝԀʎzɐɹϽ发表在《如何写出简洁优雅的代码》
  • 张志亮发表在《如何写出简洁优雅的代码》

分类

  • AI (2)
  • Java应用安全之道 (1)
    • 加密与解密 (1)
  • Odoo (2)
  • Python (1)
  • 图像处理 (1)
  • 年鉴 (1)
  • 数据库 (10)
  • 编程 (14)
    • Spring (1)
  • 读书笔记 (2)
  • 运维 (5)
  • 随笔 (10)

归档

  • 2023年1月 (2)
  • 2022年8月 (1)
  • 2022年7月 (4)
  • 2022年6月 (2)
  • 2022年5月 (2)
  • 2022年4月 (3)
  • 2021年10月 (1)
  • 2021年7月 (1)
  • 2021年5月 (1)
  • 2020年11月 (1)
  • 2020年7月 (1)
  • 2020年3月 (2)
  • 2020年2月 (1)
  • 2019年1月 (1)
  • 2018年12月 (2)
  • 2018年11月 (2)
  • 2017年4月 (1)
  • 2016年11月 (1)
  • 2016年9月 (1)
  • 2016年7月 (1)
  • 2016年5月 (3)
  • 2016年4月 (2)
  • 2016年3月 (1)
  • 2016年2月 (2)
  • 2015年12月 (1)
  • 2015年11月 (2)
  • 2015年8月 (1)
  • 2015年4月 (1)
  • 2015年3月 (1)

标签

Database devops Java MySQL PostgreSQL Python shell Spring SpringBoot Spring Security 安全 年鉴 总结 编程 随笔
© 2015-2023   Geektop.net All Rights Reserved.