Odoo _check_concurrency никогда не срабатывала?

Вместе с нашей командой мы хотели бы реализовать функцию, при которой пользователь будет предупрежден, когда запись, которую он / она обновляет, также была обновлена ​​одним из его коллег с тех пор, как он / она открыла запись.

Мы копались в исходном коде, потому что не нашли никакой официальной документации, а только некоторые модули, которые не подходили к нашей версии 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 записи на момент write

  • со значением __last_update получить из контекста, который, следовательно, должен был быть установлен в context заранее

ПРОБЛЕМА

Мы не нашли нигде в коде (python или javascript) значение, установленное в контексте => НИЧЕГО НЕ ПРОИСХОДИТ! Функция возвращается с самого начала.

Когда мы попытались жестко закодировать его в контексте, функция check_concurrency, похоже, работает правильно.

ВОПРОС

Кто-нибудь знает, где установлен __last_update или ДОЛЖЕН БЫТЬ установлен в контексте? И как ? Я бы, например, представьте себе установку как-нибудь при нажатии на кнопку редактирования записи ??? Или во время чтения ??

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
254
1

Ответы 1

CONCURRENCY_CHECK_FIELD = '__last_update'

поле параллелизма - это динамическое поле, метод вычислений которого определяется динамически, и вы также можете видеть, что оно обновляется last_modified_name = 'compute_concurrency_field_with_access' или last_modified_name = 'compute_concurrency_field' в зависимости от доступа и позже добавлены в класс. Следующие функции будут участвовать в обходном пути.

@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()

Мы также заметили этот файл как часть процесса проверки параллелизма. Однако, похоже, нам не хватает конфигурации, чтобы этот метод действительно определял одновременный доступ. Не могли бы вы сообщить мне, как я могу настроить, скажем, модель Contact, чтобы включить проверку параллелизма при обновлении на этой модели?

Anwar 12.06.2018 11:19

Другие вопросы по теме