Odoo环境变量ENV(ENVIRONMENT )

647 阅读2分钟
  • 继承了Model的类来说可以直接通过self.env得到 Environment
  • 在请求的 Controller 可以通过 request.env()得到 Environment
  • 通过模型类或模型类对象获取,cls.env、product.en

一些常用上下文参数:

  1. 当前用户 self.env.user self.env.user.name # 可以再fields.Char()里面获取当前用户名

  2. 当前用户id self.env.uid

  3. 当前语言代码 self.env.lang

  4. 当前数据库连接 self.env.cr

源码

class Environment(Mapping):
    """ An environment wraps data for ORM records:

        - :attr:`cr`, the current database cursor;
        - :attr:`uid`, the current user id;
        - :attr:`context`, the current context dictionary.

        It provides access to the registry by implementing a mapping from model
        names to new api models. It also holds a cache for records, and a data
        structure to manage recomputations.
    """
    _local = Local()

    @classproperty
    def envs(cls):
        return cls._local.environments

    def __new__(cls, cr, uid, context):
    	# 这里实现了单例模式,当env存在实例化对象且args一致时,则返回当前的env,否则再创建一个新的env对象
        assert context is not None
        args = (cr, uid, context)
        # if env already exists, return it
        env, envs = None, cls.envs
        for env in envs:
            if env.args == args:
                return env

        # otherwise create environment, and add it in the set
        self = object.__new__(cls)
        self.cr, self.uid, self.context = self.args = (cr, uid, frozendict(context))
        self.registry = Registry(cr.dbname)
        self.cache = envs.cache
        self._cache_key = (cr, uid)
        self._protected = StackMap()                # {field: ids, ...}
        self.dirty = defaultdict(set)               # {record: set(field_name), ...}
        self.all = envs
        envs.add(self)
        return self

    #
    # Mapping methods
    #

    def __getitem__(self, model_name):
    	#  该方法实现了env对model_name取key,返回封装了env的model对象
        """ Return an empty recordset from the given model. """
        return self.registry[model_name]._browse((), self)    

    def ref(self, xml_id, raise_if_not_found=True):
    	#  通过外部id获取xml记录
        """ return the record corresponding to the given ``xml_id`` """
        return self['ir.model.data'].xmlid_to_object(xml_id, raise_if_not_found=raise_if_not_found)

    @property
    def user(self):
        """ return the current user (as an instance) """
        return self(user=SUPERUSER_ID)['res.users'].browse(self.uid)

    @property
    def lang(self):
        """ return the current language code """
        return self.context.get('lang')

使用方法

  1. 利用 env[model] 获取模型类对象 self.env['ir.model'].search([('state', '!=', 'manual')])

  2. 利用 env.cr 执行sql语句 self.env.cr.execute(query, (value,))

  3. 操作缓存 self.env['模型'].create(vals) #增加一条记录

  4. 改变用户权限 self.env[‘model'].sudo().create(vals)

  5. 访问当前用户 self.env.user

  6. 获取XML的ID self.env.ref('external id')

  7. 更新缓存,触发数据库操作 self.env.invalidate_all()

self常用接口

  1. 普通查询:返回记录集,后续通过修改记录值来触发数据库修改
self.search(domain) #从当前模型的self中查询
self.env['model'].search(domain) # 获取某个model的环境,查询其中的记录集
  1. 只读查询:返回列表,只能提取内容,不能触发数据库修改 self.search_read([],['要查询的字段'])

  2. 统计数量:返回符合条件的记录条数 self.search_count(domain)

  3. 浏览:通过一系列id值,返回对应的记录集 self.browse([id])

  4. 删除 self.unlink(domain)