当前位置:   article > 正文

odoo 关于self的迭代器(0)_for record in self

for record in self

万恶之源:

  1.     @api.depends("girls", "boys")
  2.     def _compute_boys_per(self):
  3.         for record in self:
  4.             record.per = record.boys/(record.boys + record.girls)

这是一段典型的odoo的代码,作为初学者,我看了只有有点懵,在for循环内部对self和record做了print操作,发现居然是一样的,瞬间傻了。接下来的内容中,简单的说下。

  1. class BaseModel:
  2.     def __iter__(self):
  3.         """ Return an iterator over ``self``. """
  4.         for id in self._ids:
  5.             yield self._browse((id,), self.env, self._prefetch)
  6.     #
  7.     # Instance creation
  8.     # 创建实例
  9.    
  10.     # An instance represents an ordered collection of records in a given
  11.     # execution environment. The instance object refers to the environment, and
  12.     # the records themselves are represented by their cache dictionary. The 'id'
  13.     # of each record is found in its corresponding cache dictionary.
  14.     # 创建一个给定执行环境中记录的有序集合的实例。实例对象提供了环境,并且记录
  15.     # 本身由缓存字典表示。每一个记录的id都在相应的缓存字典中找到
  16.     #
  17.     # This design has the following advantages:
  18.     #  - cache access is direct and thus fast;
  19.     #  - one can consider records without an 'id' (see new records);
  20.     #  - the global cache is only an index to "resolve" a record 'id'.
  21.     #
  22.     @classmethod
  23.     def _browse(cls, ids, env, prefetch=None):
  24.         """ Create a recordset instance.
  25.         :param ids: a tuple of record ids
  26.         :param env: an environment
  27.         :param prefetch: an optional prefetch object
  28.         """
  29.         records = object.__new__(cls)
  30.         records.env = env
  31.         records._ids = ids
  32.         if prefetch is None:
  33.             prefetch = defaultdict(set)         # {model_name: set(ids)}
  34.         records._prefetch = prefetch
  35.         prefetch[cls._name].update(ids)
  36.     def browse(self, arg=None, prefetch=None):
  37.         """ browse([ids]) -> records
  38.         Returns a recordset for the ids provided as parameter in the current
  39.         environment.
  40.         Can take no ids, a single id or a sequence of ids.
  41.         这个就是格式化ids的结构
  42.         """
  43.         ids = _normalize_ids(arg) 
  44.         #assert all(isinstance(id, IdType) for id in ids), "Browsing invalid ids: %s" % ids
  45.         return self._browse(ids, self.env, prefetch)
  46.     @api.returns('self')
  47.     def exists(self):
  48.         """  exists() -> records
  49.         Returns the subset of records in ``self`` that exist, and marks deleted
  50.         records as such in cache. It can be used as a test on records::
  51. 返回self中存在的记录的子集,并且标记缓存中删除的记录。他可以用来在记录上做测试。
  52.             if record.exists():
  53.                 ...
  54.         By convention, new records are returned as existing.
  55.         """
  56.         ids, new_ids = [], []
  57.         for i in self._ids:
  58.             (ids if isinstance(i, pycompat.integer_types) else new_ids).append(i)
  59.         if not ids:
  60.             return self
  61.         query = """SELECT id FROM "%s" WHERE id IN %%s""" % self._table
  62.         self._cr.execute(query, [tuple(ids)])
  63.         ids = [r[0] for r in self._cr.fetchall()]
  64.         existing = self.browse(ids + new_ids)
  65.         if len(existing) < len(self):
  66.             # mark missing records in cache with a failed value
  67.             exc = MissingError(_("Record does not exist or has been deleted."))
  68.             self.env.cache.set_failed(self - existing, self._fields.values(), exc)
  69.         return existing

以上来自odoo/models.py

我们从下往上看

从数据库中拿到记录相关的ids

_browse创建了一个实例

__iter__用的是yield格式,每次从ids中拿出一个id,通过_browse生成这条记录的一个实例。

如果对__iter__迭代器这块有不理解请看:

odoo 关于self的迭代器(1)

odoo 关于self的迭代器(2)


声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号