Odoo17 4模型计算字段:v13缓存机制与 @api.depends_context:让计算字段更准确

核心问题:缓存机制的改变及其影响

  • 缓存 (Cache) 的目的: 缓存是一种常见的计算机技术,用于存储经常访问的数据,以便更快地检索,提高性能。
  • Odoo 缓存的目的: 在 Odoo 中,缓存用于存储模型数据,避免每次都从数据库中读取数据,从而提高读取速度。

Odoo v13 之前的缓存机制

  • 基于环境 (Environment) 的缓存:
    • 在 Odoo v13 之前,缓存是基于用户环境的 (environment-based)。
    • 环境 (Environment): Odoo 的环境是包含了数据库连接、当前用户、上下文等信息的对象。
    • 缓存特点: 每个用户环境都有自己的独立缓存,不同的用户看到的数据可能不一样, 因为他们的环境不一样, 缓存的内容也不一样。
    • 优点: 能够保证每个用户的独立视图,避免数据混淆。
    • 缺点: 缓存效率较低,因为同一个用户在多次访问相同数据的时候,也可能重复从数据库读取数据。

Odoo v13 的全局缓存机制

  • 全局缓存:
    • Odoo v13 引入了全局缓存 (global cache),这意味着整个 Odoo 系统只有一个缓存。
    • 缓存特点: 所有用户共享同一个缓存。
    • 优点: 提高了缓存效率,减少了数据库读取次数,加快了系统响应速度。
    • 缺点: 如果计算依赖上下文信息, 可能会出现问题。

上下文 (Context) 和上下文依赖

  • 上下文 (Context):
    • 上下文是 Odoo 中传递一些配置信息或临时信息的字典。
    • 它可以包含一些用户特定的信息,例如:当前用户所在的 company_id、当前用户的语言、当前用户的时区等。
    • 上下文信息通常会影响计算字段的结果。
  • 上下文依赖:
    • 如果一个计算字段的计算逻辑依赖于上下文字典中的值,我们称之为上下文依赖。
    • 例如:一个计算字段的值可能根据用户的 company_id 不同而不同。

全局缓存带来的问题

  • 缓存失效:
    • 由于全局缓存不区分环境,只缓存了计算后的值, 所以如果计算字段依赖于上下文,可能会使用缓存中上一个请求的上下文的值。
    • 导致错误结果: 例如:用户 A 的 company_id 是 1, 当用户 A 访问了该记录后, 缓存会存储基于 company_id=1 的值,当用户 B,company_id 是2访问该记录的时候, 也会读取缓存的值,导致用户B 读取了基于 company_id=1 的值, 出现了错误的结果。
    • 问题根源: 缓存无法识别上下文变化, 还是读取了旧的上下文对应的值。

@api.depends_context 的作用

  • 解决上下文依赖问题:
    • @api.depends_context 修饰符告诉 Odoo,这个计算字段依赖于哪些上下文信息。
    • 语法: @api.depends_context('context_key1', 'context_key2', ...), 将你依赖的上下文 key 放进去。
  • 缓存更新:
    • 当上下文中依赖的键值发生变化时,Odoo 会自动使缓存失效,并重新计算字段的值。
    • 保证数据正确: 可以确保计算结果始终基于当前正确的上下文,避免了数据错误。

代码示例再次解读

    @api.depends('price')
    @api.depends_context('company_id')
    def _compute_value(self):
        company_id = self.env.context.get('company_id')
        ...
        # 其他计算
  1. @api.depends('price') 表示该计算字段依赖于 price 字段的值, 当 price 字段改变的时候,会重新计算。
  2. @api.depends_context('company_id')
    • 表示该计算字段依赖于上下文中的 company_id 的值。
    • 当上下文中的 company_id 值发生变化时,Odoo 会重新计算该字段的值。
  3. company_id = self.env.context.get('company_id') 从上下文字典中读取 company_id 的值。
  4. 其他计算: 根据 company_id 的值进行相应的计算。

总结

  • Odoo v13 的全局缓存: 可以提高效率,但带来了上下文依赖的问题。
  • @api.depends_context
    • 用于标记那些依赖于上下文的计算字段。
    • 当依赖的上下文字典中的值发生变化时,Odoo 会重新计算字段的值。
    • 确保了计算结果的正确性。

用一个比喻来说明:

  • 全局缓存就像一个大的公共图书馆: 所有人都从这个图书馆借书,速度很快,但是图书馆里的图书都是事先分类好的,不能根据你个人情况推荐书。
  • @api.depends_context 就像图书馆的个性化推荐系统: 它会根据你的身份 (上下文) ,比如你是学生, 给你推荐学生相关的书籍。 如果你成了老师, 推荐系统会重新根据你的老师身份推荐书籍, 确保你看到的是最符合你当前情况的书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值