odoo17核心概念——env

env在odoo中是一个非常重要的概念,它是一个全局变量,保存了odoo运行环境的重要信息,env分为前端和后端

一、环境(env)

1、前端的env

在web\static\src\env.js中定义,包含两个重要的对象:

  • 全局数据总线bus, 可以在不同的组件之间进行通信
  • 所有的服务services

这个文件非常重要,它定义了两个函数

makeEnv: 初始化env对象。

export function makeEnv() {return {bus: new EventBus(),services: {},debug: odoo.debug,get isSmall() {throw new Error("UI service not initialized!");},};
}

startServices: 启动所有的Service, 这个函数的实现非常巧妙,因为它要在不考虑服务加载顺序的前提下解决服务之间的依赖问题。 其中细节,值得一读。

不过这里只有这两个函数的定义,并没有执行这两个函数, 真正执行这两个函数的位置在 start.js中

const env = makeEnv();
await startServices(env);

服务启动完后, 会放入env的services对象中。 注意其中放的不是服务对象本身,而是start函数的返回值。

2、 后端的env

后端的env在odoo\api.py中定义

"""The Odoo API module defines Odoo Environments and method decorators... todo:: Document this module
"""__all__ = ['Environment','Meta','model','constrains', 'depends', 'onchange', 'returns','call_kw',
]

文件的注释中说明了两点:
1、这个文件定义了odoo环境和方法装饰器
2、todo: 要为这个模块写文档(啥时候写?)
默认导出的对象,odoo后端最重要的一些对象
‘Environment’,
‘Meta’,
‘model’,
‘constrains’, ‘depends’, ‘onchange’, ‘returns’,
‘call_kw’,

from collections.abc import Mappingclass Environment(Mapping):""" The environment stores various contextual data used by the ORM:- :attr:`cr`: the current database cursor (for database queries);- :attr:`uid`: the current user id (for access rights checks);- :attr:`context`: the current context dictionary (arbitrary metadata);- :attr:`su`: whether in superuser mode.It provides access to the registry by implementing a mapping from modelnames to models. It also holds a cache for records, and a datastructure to manage recomputations."""def reset(self):""" Reset the transaction, see :meth:`Transaction.reset`. """self.transaction.reset()def __new__(cls, cr, uid, context, su=False):if uid == SUPERUSER_ID:su = Trueassert context is not Noneargs = (cr, uid, context, su)# determine transaction objecttransaction = cr.transactionif transaction is None:transaction = cr.transaction = Transaction(Registry(cr.dbname))# if env already exists, return itfor env in transaction.envs:if env.args == args:return env# otherwise create environment, and add it in the setself = object.__new__(cls)args = (cr, uid, frozendict(context), su)self.cr, self.uid, self.context, self.su = self.args = argsself.transaction = self.all = transactionself.registry = transaction.registryself.cache = transaction.cacheself._cache_key = {}                    # memo {field: cache_key}self._protected = transaction.protectedtransaction.envs.add(self)return self

env对象存储了不同类型的上下文数据被ORM使用,
- :attr:cr: the current database cursor (for database queries);
- :attr:uid: the current user id (for access rights checks);
- :attr:context: the current context dictionary (arbitrary metadata);
- :attr:su: whether in superuser mode.

env继承自 collection 的Mapping

在文件的末尾有两句import有点意思

# keep those imports here in order to handle cyclic dependencies correctly
from odoo import SUPERUSER_ID
from odoo.modules.registry import Registry

之所以放在文件末尾,是为了正确的处理循环依赖。 姑且先不管的原理是啥了,不过这里引入了一个重要的对象 Regisitry ——后端的注册表

class Registry(Mapping):""" Model registry for a particular database.The registry is essentially a mapping between model names and model classes.There is one registry instance per database."""_lock = threading.RLock()_saved_lock = None@lazy_classpropertydef registries(cls):""" A mapping from database names to registries. """size = config.get('registry_lru_size', None)if not size:# Size the LRU depending of the memory limitsif os.name != 'posix':# cannot specify the memory limit soft on windows...size = 42else:# A registry takes 10MB of memory on average, so we reserve# 10Mb (registry) + 5Mb (working memory) per registryavgsz = 15 * 1024 * 1024size = int(config['limit_memory_soft'] / avgsz)return LRU(size)def __new__(cls, db_name):""" Return the registry for the given database name."""with cls._lock:try:return cls.registries[db_name]except KeyError:return cls.new(db_name)finally:# set db tracker - cleaned up at the WSGI dispatching phase in# odoo.http.rootthreading.current_thread().dbname = db_name

这里不想写的过于深入,先摸清系统的大概框架,在需要的时候再去扣细节,这才是学习的正确方法 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/236110.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一键在线获取APP公钥、包名、签名及备案信息方法介绍

​ 目录 一键在线获取APP公钥、包名、签名及备案信息方法介绍 摘要 引言 一键获取APP包信息 操作步骤 ​编辑 解析报告 总结 致谢 关键词 参考资料 声明 摘要 本文介绍了一款在线APP解析工具,可以一键获取APP的公钥、包名、签名等基础信息,…

Python教程:对于初学者,几个易懂的装饰器示例用法

装饰器是Python中的一个高级功能,它可以用来扩展或修改一个函数或方法的功能,而不需要修改其原始代码。装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数对象。 装饰器通常用于添加与函数功能无关的额外功能&a…

矩阵秩的公式小结

文章目录 矩阵秩的公式说明公式 矩阵秩的公式 说明 解释下了公式时,注意矩阵的行数列数由三秩相等原理,向量组的秩往往转换为矩阵的秩来研究 线性方程组 A x b \bold{Axb} Axb或 A X B \bold{AXB} AXB型方程有解定理 R ( A ) ⩽ R ( A , B ) R(\bold{A})\leqslant{R(\bold{…

java中IO与NIO有什么不同

目录 1. 阻塞与非阻塞 2. 缓冲区(Buffer) 3. 选择器(Selector) 4. 面向流与面向缓冲 5. 非阻塞IO Java中的IO(Input/Output)和NIO(New I/O)都是用于处理输入和输出的API&#x…

LeetCode 647回文子串 517最长回文子序列 | 代码随想录25期训练营day57

动态规划算法14 LeetCode 647 回文子串 2023.12.20 题目链接代码随想录讲解[链接] int countSubstrings(string s) {//暴力搜索&#xff0c;前两层遍历确定子字符串的起始和末尾位置//第三层循环判断当前子字符串是否为回文串/*int result 0;for (int i 0; i < s.size…

灰盒测试简要学习指南!

在本文中&#xff0c;我们将了解什么是灰盒测试、以及为什么要使用它&#xff0c;以及它的优缺点。 在软件测试中&#xff0c;灰盒测试是一种有用的技术&#xff0c;可以确保发布的软件是高性能的、安全的并满足预期用户的需求。这是一种从外部测试应用程序同时跟踪其内部操作…

2023 英特尔On技术创新大会直播 | 窥探未来科技的边界

2023 英特尔On技术创新大会直播 | 窥探未来科技的边界 写在最前面观后感其他有趣的专题课程 写在最前面 嘿&#xff0c;你是不是对科技和创新充满好奇&#xff1f;2023 英特尔 On 技术创新大会线上活动邀请你一起探索最前沿的科技世界&#xff01; 这不仅是一场普通的聚会&…

golang开发--beego入门

Beego 是一个基于 Go 语言的开源框架&#xff0c;用于构建 Web 应用程序和 API。它采用了一些常见的设计模式&#xff0c;以提高开发效率、代码可维护性和可扩展性。 一&#xff0c;MVC设计模式 Beego 框架采用了经典的 MVC&#xff08;Model-View-Controller&#xff09;设计…

Linux 上Redis 升级

背景&#xff1a; 随着我Ruby on Rails 的版本升级&#xff0c;sidekiq的升级&#xff0c;我的redis已经不能很好的支持了&#xff0c;当我启动sidekiq时出现如下报错&#xff1a; redis-client requires Redis 6 with HELLO command available (redis://127.0.0.1:6379/0) 意…

程序员的23大IONIO面试问题及答案

文章目录 1. 什么是IO流&#xff1f;2.java中有几种类型的流&#xff1f;3.字节流和字符流哪个好&#xff1f;怎么选择&#xff1f;4.读取数据量大的文件时&#xff0c;速度会很慢&#xff0c;如何选择流&#xff1f;5. IO模型有几种&#xff1f;6.阻塞IO &#xff08;blocking…

如何用Excel制作一张能在网上浏览的动态数据报表

前言 如今各类BI产品大行其道&#xff0c;“数据可视化”成为一个热门词汇。相比价格高昂的各种BI软件&#xff0c;用Excel来制作动态报表就更加经济便捷。今天小编就将为大家介绍一下如何使用葡萄城公司的纯前端表格控件——SpreadJS来实现一个Excel动态报表&#xff1a; 实…

华为鸿蒙操作系统简介及系统架构分析(2)

接前一篇文章&#xff1a;华为鸿蒙操作系统简介及系统架构分析&#xff08;1&#xff09; 本文部分内容参考&#xff1a; 鸿蒙系统学习笔记(一) 鸿蒙系统介绍 特此致谢&#xff01; 上一回对于华为的鸿蒙操作系统&#xff08;HarmonyOS&#xff09;进行了介绍并说明了其层次化…

C语言——高精度乘法

一、引子 高精度乘法相较于高精度加法和减法有更多的不同&#xff0c;加法和减法是一位对应一位进行操作的&#xff0c;而乘法是一个数的每一位对另一个数的每一位进行操作&#xff0c;需要的计算步骤更多。 二、核心算法 void Calculate(int num1[], int num2[], int numres…

代理IP解决了哪些问题?如何切换IP地址?

代理IP主要解决了以下问题&#xff1a; 1. 隐私保护&#xff1a;通过代理IP&#xff0c;用户可以隐藏自己的真实IP地址&#xff0c;增强网络匿名性&#xff0c;保护个人信息不被泄露。 2. 地理位置限制&#xff1a;某些网站或服务可能会根据用户的IP地址实施地域限制。使用代…

Linux使用javac编译报错-bash: javac: command not found

如果在Linux上使用javac编译时出现错误"bash: javac: command not found"&#xff0c;这通常意味着您的系统没有正确安装Java开发工具包&#xff08;JDK&#xff09;。 请按照以下步骤检查和解决该问题&#xff1a; 首先&#xff0c;确保已安装Java开发工具包&…

echart图表之仪表盘 pie 双盘 乃至多盘

效果展示&#xff1a; 代码&#xff1a; //首页转速盘 export const pieSpeed (params) > {let demoDataif (params.length ! 0) {demoData params?.map(item > {return {title: item.title,name: item.name,value: item.value,unit: item.unit || ,pos: item.pos,ran…

Android Studio开发之路(六)(合集)界面优化以及启动图标等

一、导航栏背景、字体修改 导航栏、状态栏等背景颜色的修改一般是在themes.xml文件中修改&#xff0c;android一个activity各个部件参考&#xff1a; colorPrimary,colorPrimaryDark等的意义 添加链接描述 但是问题在于&#xff1a;只在这里修改背景颜色的话&#xff0c;可能…

Google 提示:切忌滥用 DORA 指标

谷歌的 DevOps 研究与评估团队从事指标交易&#xff0c;即 DevOps 指标。但其最新的相关报告也警告不要过度使用这些指标。 DevOps 研究与评估小组&#xff08;DORA&#xff09;建议 IT 专业人员根据四个关键指标来评估团队绩效&#xff1a;部署频率&#xff0c;变更准备时间&a…

ubuntu18 安装 cmake v3.26.1

ubuntu18 安装 cmake v3.26.1 下载 & 解压configure 配置 & 安装 下载 & 解压 版本 v3.26.1 地址直接下载 https://cmake.org/files/v3.26/cmake-3.26.1.tar.gz wget命令下载 wget https://cmake.org/files/v3.26/cmake-3.26.1.tar.gz 解压 tar -xvzf cmake-3.2…

服务器不稳定因素

服务器不稳定因素 外贸网站主要目的是达到企业和客户紧密联系&#xff0c;提升客户对企业形象的认知度的效果&#xff0c;若租用的服务器不稳定&#xff0c;不仅影响网站的运行&#xff0c;对于网站搜索引擎优化以及用户体验等也有很大的影响&#xff0c;也会照成外贸企业的损失…