在想做批量更新数据的时候。发现了个问题。直接
self.env[''].write({}) 是不生效的。。查询资料发现:
model.create() records.write()。。这样的话。作为开发人员。肯定要搞清这个关系
一、搞清model在哪
由于 odoo 是动态加载model的。所以要先搞清 当前的model 是 什么类型
随便找个 model。可以操作的地方
print(self.__class__)
<class 'odoo.api.zhy.sale'> 。。可以看出。所有是被动态加载到 odoo.api 模块里面了
二、record 和model 如何区分
调试可以看出
然后for order in self:
。。可以看出。肯定重写了 model的一些魔法函数
def __str__(self):
return "%s%s" % (self._name, getattr(self, '_ids', ""))
可以看出。_ids 属性 是 影响 为record 和model 的关键了
三、self.env["**"] 什么鬼
class Environment(Mapping):
class Environment(Mapping):
def __new__(cls, cr, uid, context):
assert context is not None
args = (cr, uid, context)
# if env already exists, return it 这句就是全局envs
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
def __getitem__(self, model_name):
""" Return an empty recordset from the given model. """
return self.registry[model_name]._browse((), self)
首先 cls.envs 全局变量保存 了所有的 env
然后重写了 [] 。self.env[''] 相当于 获取注册的model 然后 _browse 一个空的record() (空的reocord 可以理解为model,里面初始化一些其他参数了)
所以self.env[''] 就是获取了一个 空的record(model)
self.registry[model_name] 为 没 _browse 的model
四、_browse 是什么
@classmethod
def _browse(cls, ids, env, prefetch=None, add_prefetch=True):
""" Create a recordset instance.
:param ids: a tuple of record ids
:param env: an environment
:param prefetch: an optional prefetch object
"""
records = object.__new__(cls)
records.env = env
records._ids = ids
if prefetch is None:
prefetch = defaultdict(set) # {model_name: set(ids)}
records._prefetch = prefetch
if add_prefetch:
prefetch[cls._name].update(ids)
return records
可以看出。就是生成一个model,然后把传入的id给赋值上
这样的好处是: 只有遍历的时候(确定需要record)的时候才会生成真正的record。来使用。其他都是一个record(_ids)来表示。减少很大的内存空间了
具体如何写入ids 的。请看二做的分析
五、self.env[''].write({}) 为什么不生效
计入 self.env[""] 也就是model。为什么wirte 不能生效
看下 write 代码
@api.multi
def write(self, vals):
# 所以这里只能是记录
if not self:
return True
这里可以看到。model 肯定重写了_bool_魔法函数,
def __bool__(self):
""" Test whether ``self`` is nonempty. """
return bool(getattr(self, '_ids', True))
可以看到。model 的 true和flase 是根据 _ids决定的。
self.registry[model_name]._browse((), self)
_ids=()
所以 self.env[""] 的_ids属性是 {}。
无法批量wirte的