python - Odoo _check_concurrency 从未触发过?

标签 python concurrency odoo odoo-11

与我们的团队一起,我们希望实现一项功能,当他/她正在更新的记录在他/她打开记录后也被他/她的一位同事更新时,用户会收到警告。

我们深入研究了源代码,因为我们没有找到任何官方文档,只有一些不适合我们的 Odoo 版本 (11) 的模块。

我们在文件/odoo/odoo/models.py中找到方法def _check_concurrency(self):,代码如下:

    @api.multi
    def _check_concurrency(self):
        if not (self._log_access and self._context.get(self.CONCURRENCY_CHECK_FIELD)):
            return
        check_clause = "(id = %s AND %s < COALESCE(write_date, create_date, (now() at time zone 'UTC'))::timestamp)"
        for sub_ids in self._cr.split_for_in_conditions(self.ids):
            nclauses = 0
            params = []
            for id in sub_ids:
                id_ref = "%s,%s" % (self._name, id)
                update_date = self._context[self.CONCURRENCY_CHECK_FIELD].pop(id_ref, None)
                if update_date:
                    nclauses += 1
                    params.extend([id, update_date])
            if not nclauses:
                continue
            query = "SELECT id FROM %s WHERE %s" % (self._table, " OR ".join([check_clause] * nclauses))
            self._cr.execute(query, tuple(params))
            res = self._cr.fetchone()
            if res:
                # mention the first one only to keep the error message readable
                raise ValidationError(_('A document was modified since you last viewed it (%s:%d)') % (self._description, res[0]))

=> 此方法在任何“写入”之前调用。它比较:

  • 写入

    时记录的__last_update
  • __last_update 的值从上下文中获取,因此应该事先在 context 中设置

问题

我们没有在代码(python 或 javascript)的任何地方找到在上下文中设置的值 => 没有发生!该函数从头开始返回。

当我们尝试在上下文中对其进行硬编码时,函数 check_concurrency 似乎可以正常工作。

问题

有谁知道 __last_update 在哪里设置或应该在上下文中设置?如何 ? 我会例如想象一下在单击记录的编辑按钮时以某种方式设置它???或者在阅读时??

最佳答案

CONCURRENCY_CHECK_FIELD = '__last_update'

concurrency 字段是一个动态字段,它的计算方法是动态定义的,你也可以看到它是由 last_modified_name = 'compute_concurrency_field_with_access'last_modified_name = 'compute_concurrency_field' 根据 access 然后添加到类中。以下函数将参与解决方法。

@api.model
    def _add_magic_fields(self):
        """ Introduce magic fields on the current class

        * id is a "normal" field (with a specific getter)
        * create_uid, create_date, write_uid and write_date have become
          "normal" fields
        * $CONCURRENCY_CHECK_FIELD is a computed field with its computing
          method defined dynamically. Uses ``str(datetime.datetime.utcnow())``
          to get the same structure as the previous
          ``(now() at time zone 'UTC')::timestamp``::

              # select (now() at time zone 'UTC')::timestamp;
                        timezone
              ----------------------------
               2013-06-18 08:30:37.292809

              >>> str(datetime.datetime.utcnow())
              '2013-06-18 08:31:32.821177'
        """
        def add(name, field):
            """ add ``field`` with the given ``name`` if it does not exist yet """
            if name not in self._fields:
                self._add_field(name, field)

        # cyclic import
        from . import fields

        # this field 'id' must override any other column or field
        self._add_field('id', fields.Id(automatic=True))

        add('display_name', fields.Char(string='Display Name', automatic=True,
            compute='_compute_display_name'))

        if self._log_access:
            add('create_uid', fields.Many2one('res.users', string='Created by', automatic=True))
            add('create_date', fields.Datetime(string='Created on', automatic=True))
            add('write_uid', fields.Many2one('res.users', string='Last Updated by', automatic=True))
            add('write_date', fields.Datetime(string='Last Updated on', automatic=True))
            last_modified_name = 'compute_concurrency_field_with_access'
        else:
            last_modified_name = 'compute_concurrency_field'

        # this field must override any other column or field
        self._add_field(self.CONCURRENCY_CHECK_FIELD, fields.Datetime(
            string='Last Modified on', compute=last_modified_name, automatic=True))

    def compute_concurrency_field(self):
        for record in self:
            record[self.CONCURRENCY_CHECK_FIELD] = odoo.fields.Datetime.now()

    @api.depends('create_date', 'write_date')
    def compute_concurrency_field_with_access(self):
        for record in self:
            record[self.CONCURRENCY_CHECK_FIELD] = \
                record.write_date or record.create_date or odoo.fields.Datetime.now()

关于python - Odoo _check_concurrency 从未触发过?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50685432/

相关文章:

Python:定义正则表达式的并集

java - scheduleWithFixedDelay 抛出异常如何重启schedule?

python - 在加载所有记录并调用 fields_view_get 函数后动态触发 Odoo fields_view_get

python - 堆叠小部件页面

python - Sklearn K表示Clustering convergence

Python:理解对象 __del__ 方法

postgresql - 管理数以万计的桌面应用程序用户访问 PostgreSQL 数据库的最佳解决方案

TCP accept and Go 并发模型

javascript - 在 TreeView Odoo 中单击时禁用日期选择器

javascript - ODOO报告自动将字符<转换为<