与我们的团队一起,我们希望实现一项功能,当他/她正在更新的记录在他/她打开记录后也被他/她的一位同事更新时,用户会收到警告。
我们深入研究了源代码,因为我们没有找到任何官方文档,只有一些不适合我们的 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/