Use a sequence of records, values in write

issue3499
review1641003
This commit is contained in:
Cédric Krier committed 2013-12-19 14:44:01 +01:00
1 parent c46a026c40
commit f52fe8e45f
23 files changed
+291 -199

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Use a sequence of records, values in write
* set_context of Transaction.set_user is restricted to root
* Add a "copy" action to One2Many and Many2Many's set method
* Force UTC as timezone (migration script available on tryton-tools)
+2 -2
View File
@@ -495,8 +495,8 @@ This field accepts as written value a list of tuples like this:
- ``('create', [{<field name>: value, ...}, ...])``: it will create new
target records and link them to this one.
- ``('write'[, ids, ...], {<field name>: value, ...})``: it will write
values to target ids.
- ``('write'[[, ids, ...], {<field name>: value, ...}, ...])``: it will
write values to target ids.
- ``('delete'[, ids, ...])``: it will delete the target ids.
+1 -1
View File
@@ -238,7 +238,7 @@ CLass methods:
Return a list of values for the ids. If ``fields_names`` is set, there will
be only values for these fields otherwise it will be for all fields.
.. classmethod:: ModelStorage.write(records, values)
.. classmethod:: ModelStorage.write(records, values, [[records, values], ...])
Write ``values`` on the list of records. ``values`` is a dictionary with
fields names as key and writen values as value.
+1 -1
View File
@@ -17,7 +17,7 @@ Instance attributes are:
.. attribute:: RPC.instantiate
The position of the argument to be instanciated
The position or the slice of the argument to be instanciated
.. attribute:: RPC.result
+67 -36
View File
@@ -402,6 +402,8 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
self.module_state = module_state
self.grouped = None
self.grouped_creations = defaultdict(dict)
self.grouped_write = defaultdict(list)
self.grouped_model_data = []
self.skip_data = False
# Tag handlders are used to delegate the processing
@@ -475,6 +477,13 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
for model, values in self.grouped_creations.iteritems():
self.create_records(model, values.values(), values.keys())
self.grouped_creations.clear()
for key, actions in self.grouped_write.iteritems():
module, model = key
self.write_records(module, model, *actions)
self.grouped_write.clear()
if self.grouped_model_data:
self.ModelData.write(*self.grouped_model_data)
del self.grouped_model_data[:]
# Closing tag found, if we are in a delegation the handler
# know what to do:
@@ -664,42 +673,12 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
# and no user changed the value in the db:
to_update[key] = values[key]
# if there is values to update:
if to_update:
# write the values in the db:
with Transaction().set_context(
module=module, language='en_US'):
Model.write([record], to_update)
self.fs2db.reset_browsercord(
module, Model.__name__, [record.id])
if to_update:
# re-read it: this ensure that we store the real value
# in the model_data table:
record = self.fs2db.get_browserecord(
module, Model.__name__, record.id)
if not record:
record = Model(record.id)
for key in to_update:
values[key] = self._clean_value(key, record)
if module != self.module:
temp_values = old_values.copy()
temp_values.update(values)
values = temp_values
if values != old_values:
self.ModelData.write([self.ModelData(mdata_id)], {
'fs_id': fs_id,
'model': model,
'module': module,
'db_id': record.id,
'values': str(values),
'date_update': datetime.datetime.now(),
})
# reset_browsercord to keep cache memory low
self.fs2db.reset_browsercord(module, Model.__name__, [record.id])
if self.grouped:
self.grouped_write[(module, model)].extend(
(record, to_update, old_values, fs_id, mdata_id))
else:
self.write_records(module, model, record, to_update,
old_values, fs_id, mdata_id)
else:
if self.grouped:
self.grouped_creations[model][fs_id] = values
@@ -739,6 +718,58 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
self.fs2db.reset_browsercord(self.module, model,
[r.id for r in records])
def write_records(self, module, model,
record, values, old_values, fs_id, mdata_id, *args):
args = (record, values, old_values, fs_id, mdata_id) + args
Model = self.pool.get(model)
actions = iter(args)
to_update = []
for record, values, _, _, _ in zip(*((actions,) * 5)):
if values:
to_update += [[record], values]
# if there is values to update:
if to_update:
# write the values in the db:
with Transaction().set_context(
module=module, language='en_US'):
Model.write(*to_update)
self.fs2db.reset_browsercord(
module, Model.__name__, sum(to_update[::2], []))
actions = iter(to_update)
for records, values in zip(actions, actions):
record, = records
# re-read it: this ensure that we store the real value
# in the model_data table:
record = self.fs2db.get_browserecord(
module, Model.__name__, record.id)
if not record:
record = Model(record.id)
for key in values:
values[key] = self._clean_value(key, record)
actions = iter(args)
for record, values, old_values, fs_id, mdata_id in zip(
*((actions,) * 5)):
if module != self.module:
temp_values = old_values.copy()
temp_values.update(values)
values = temp_values
if values != old_values:
self.grouped_model_data.extend(([self.ModelData(mdata_id)], {
'fs_id': fs_id,
'model': model,
'module': module,
'db_id': record.id,
'values': str(values),
'date_update': datetime.datetime.now(),
}))
# reset_browsercord to keep cache memory low
self.fs2db.reset_browsercord(module, Model.__name__, args[::5])
def post_import(pool, module, to_delete):
"""
+22 -14
View File
@@ -56,9 +56,9 @@ class Action(ModelSQL, ModelView):
return True
@classmethod
def write(cls, actions, values):
def write(cls, actions, values, *args):
pool = Pool()
super(Action, cls).write(actions, values)
super(Action, cls).write(actions, values, *args)
pool.get('ir.action.keyword')._get_keyword_cache.clear()
@classmethod
@@ -194,9 +194,12 @@ class ActionKeyword(ModelSQL, ModelView):
return super(ActionKeyword, cls).create(new_vlist)
@classmethod
def write(cls, keywords, vals):
vals = cls._convert_vals(vals)
super(ActionKeyword, cls).write(keywords, vals)
def write(cls, keywords, values, *args):
actions = iter((keywords, values) + args)
args = []
for keywords, values in zip(actions, actions):
args.extend((keywords, cls._convert_vals(values)))
super(ActionKeyword, cls).write(*args)
ModelView._fields_view_get_cache.clear()
ModelView._view_toolbar_get_cache.clear()
cls._get_keyword_cache.clear()
@@ -329,10 +332,10 @@ class ActionMixin(ModelSQL):
return new_records
@classmethod
def write(cls, records, values):
def write(cls, records, values, *args):
pool = Pool()
ActionKeyword = pool.get('ir.action.keyword')
super(ActionMixin, cls).write(records, values)
super(ActionMixin, cls).write(records, values, *args)
ActionKeyword._get_keyword_cache.clear()
@classmethod
@@ -645,13 +648,18 @@ class ActionReport(ActionMixin, ModelSQL, ModelView):
return new_reports
@classmethod
def write(cls, reports, vals):
def write(cls, reports, values, *args):
context = Transaction().context
if 'module' in context:
vals = vals.copy()
vals['module'] = context['module']
super(ActionReport, cls).write(reports, vals)
actions = iter((reports, values) + args)
args = []
for reports, values in zip(actions, actions):
values = values.copy()
values['module'] = context['module']
args.extend((reports, values))
reports, values = args[:2]
args = args[2:]
super(ActionReport, cls).write(reports, values, *args)
class ActionActWindow(ActionMixin, ModelSQL, ModelView):
@@ -908,9 +916,9 @@ class ActionActWindowView(ModelSQL, ModelView):
return windows
@classmethod
def write(cls, windows, values):
def write(cls, windows, values, *args):
pool = Pool()
super(ActionActWindowView, cls).write(windows, values)
super(ActionActWindowView, cls).write(windows, values, *args)
pool.get('ir.action.keyword')._get_keyword_cache.clear()
@classmethod
+8 -4
View File
@@ -231,10 +231,14 @@ class Attachment(ModelSQL, ModelView):
super(Attachment, cls).delete(attachments)
@classmethod
def write(cls, attachments, vals):
cls.check_access([a.id for a in attachments], mode='write')
super(Attachment, cls).write(attachments, vals)
cls.check_access(attachments, mode='write')
def write(cls, attachments, values, *args):
all_attachments = []
actions = iter((attachments, values) + args)
for records, _ in zip(actions, actions):
all_attachments += records
cls.check_access([a.id for a in all_attachments], mode='write')
super(Attachment, cls).write(attachments, values, *args)
cls.check_access(all_attachments, mode='write')
@classmethod
def create(cls, vlist):
+2 -2
View File
@@ -213,12 +213,12 @@ class Lang(ModelSQL, ModelView):
return languages
@classmethod
def write(cls, langs, vals):
def write(cls, langs, values, *args):
pool = Pool()
Translation = pool.get('ir.translation')
# Clear cache
cls._lang_cache.clear()
super(Lang, cls).write(langs, vals)
super(Lang, cls).write(langs, values, *args)
Translation._get_language_cache.clear()
@classmethod
+10 -10
View File
@@ -139,10 +139,10 @@ class Model(ModelSQL, ModelView):
return res
@classmethod
def write(cls, models, vals):
def write(cls, models, values, *args):
pool = Pool()
Property = pool.get('ir.property')
super(Model, cls).write(models, vals)
super(Model, cls).write(models, values, *args)
# Restart the cache of models_get
Property._models_get_cache.clear()
@@ -527,8 +527,8 @@ class ModelAccess(ModelSQL, ModelView):
return True
@classmethod
def write(cls, accesses, vals):
super(ModelAccess, cls).write(accesses, vals)
def write(cls, accesses, values, *args):
super(ModelAccess, cls).write(accesses, values, *args)
# Restart the cache
cls._get_access_cache.clear()
ModelView._fields_view_get_cache.clear()
@@ -681,8 +681,8 @@ class ModelFieldAccess(ModelSQL, ModelView):
return True
@classmethod
def write(cls, field_accesses, vals):
super(ModelFieldAccess, cls).write(field_accesses, vals)
def write(cls, field_accesses, values, *args):
super(ModelFieldAccess, cls).write(field_accesses, values, *args)
# Restart the cache
cls._get_access_cache.clear()
ModelView._fields_view_get_cache.clear()
@@ -730,8 +730,8 @@ class ModelButton(ModelSQL, ModelView):
return result
@classmethod
def write(cls, buttons, values):
super(ModelButton, cls).write(buttons, values)
def write(cls, buttons, values, *args):
super(ModelButton, cls).write(buttons, values, *args)
# Restart the cache for get_groups
cls._groups_cache.clear()
@@ -813,8 +813,8 @@ class ModelData(ModelSQL, ModelView):
return False
@classmethod
def write(cls, data, values):
super(ModelData, cls).write(data, values)
def write(cls, data, values, *args):
super(ModelData, cls).write(data, values, *args)
# Restart the cache for get_id
cls._get_id_cache.clear()
+4 -4
View File
@@ -86,8 +86,8 @@ class RuleGroup(ModelSQL, ModelView):
return res
@classmethod
def write(cls, groups, vals):
super(RuleGroup, cls).write(groups, vals)
def write(cls, groups, vals, *args):
super(RuleGroup, cls).write(groups, vals, *args)
# Restart the cache on the domain_get method of ir.rule
Pool().get('ir.rule')._domain_get_cache.clear()
@@ -276,7 +276,7 @@ class Rule(ModelSQL, ModelView):
return res
@classmethod
def write(cls, rules, vals):
super(Rule, cls).write(rules, vals)
def write(cls, rules, vals, *args):
super(Rule, cls).write(rules, vals, *args)
# Restart the cache on the domain_get method
cls._domain_get_cache.clear()
+6 -5
View File
@@ -184,12 +184,13 @@ class Sequence(ModelSQL, ModelView):
return sequences
@classmethod
def write(cls, sequences, values):
result = super(Sequence, cls).write(sequences, values)
def write(cls, sequences, values, *args):
super(Sequence, cls).write(sequences, values, *args)
if sql_sequence and not cls._strict:
for sequence in sequences:
sequence.update_sql_sequence(values.get('number_next'))
return result
actions = iter((sequences, values) + args)
for sequences, values in zip(actions, actions):
for sequence in sequences:
sequence.update_sql_sequence(values.get('number_next'))
@classmethod
def delete(cls, sequences):
+9 -5
View File
@@ -731,13 +731,17 @@ class Translation(ModelSQL, ModelView):
return super(Translation, cls).create(vlist)
@classmethod
def write(cls, translations, vals):
def write(cls, translations, values, *args):
cls._translation_cache.clear()
ModelView._fields_view_get_cache.clear()
if 'src' in vals:
vals = vals.copy()
vals['src_md5'] = cls.get_src_md5(vals.get('src'))
return super(Translation, cls).write(translations, vals)
actions = iter((translations, values) + args)
args = []
for translations, values in zip(actions, actions):
if 'src' in values:
values = values.copy()
values['src_md5'] = cls.get_src_md5(values.get('src'))
args.extend((translations, values))
return super(Translation, cls).write(*args)
@classmethod
def extra_model_data(cls, model_data):
+2 -3
View File
@@ -270,11 +270,10 @@ class Trigger(ModelSQL, ModelView):
return res
@classmethod
def write(cls, ids, values):
res = super(Trigger, cls).write(ids, values)
def write(cls, triggers, values, *args):
super(Trigger, cls).write(triggers, values, *args)
# Restart the cache on the get_triggers method of ir.trigger
cls._get_triggers_cache.clear()
return res
@classmethod
def delete(cls, records):
+4 -4
View File
@@ -196,8 +196,8 @@ class View(ModelSQL, ModelView):
return views
@classmethod
def write(cls, views, vals):
super(View, cls).write(views, vals)
def write(cls, views, values, *args):
super(View, cls).write(views, values, *args)
# Restart the cache
ModelView._fields_view_get_cache.clear()
@@ -260,8 +260,8 @@ class ViewTreeWidth(ModelSQL, ModelView):
return res
@classmethod
def write(cls, records, vals):
super(ViewTreeWidth, cls).write(records, vals)
def write(cls, records, values, *args):
super(ViewTreeWidth, cls).write(records, values, *args)
ModelView._fields_view_get_cache.clear()
@classmethod
+4 -2
View File
@@ -101,7 +101,7 @@ class Many2Many(Field):
values: A list of tuples:
(``create``, ``[{<field name>: value}, ...]``),
(``write``, ``<ids>``, ``{<field name>: value}``),
(``write``, [``<ids>``, ``{<field name>: value}``, ...]),
(``delete``, ``<ids>``),
(``delete_all``),
(``unlink``, ``<ids>``),
@@ -142,7 +142,9 @@ class Many2Many(Field):
if to_create:
Relation.create(to_create)
elif act[0] == 'write':
Target.write(Target.browse(act[1]), act[2])
actions = iter(act[1:])
Target.write(*sum(((Target.browse(ids), values)
for ids, values in zip(actions, actions)), ()))
elif act[0] == 'delete':
Target.delete(Target.browse(act[1]))
elif act[0] == 'delete_all':
+15 -5
View File
@@ -107,7 +107,7 @@ class One2Many(Field):
Set the values.
values: A list of tuples:
(``create``, ``[{<field name>: value}, ...]``),
(``write``, ``<ids>``, ``{<field name>: value}``),
(``write``, [``<ids>``, ``{<field name>: value}``, ...]),
(``delete``, ``<ids>``),
(``delete_all``),
(``unlink``, ``<ids>``),
@@ -146,7 +146,9 @@ class One2Many(Field):
if to_create:
Target.create(to_create)
elif act[0] == 'write':
Target.write(Target.browse(act[1]), act[2])
actions = iter(act[1:])
Target.write(*sum(((Target.browse(ids), values)
for ids, values in zip(actions, actions)), ()))
elif act[0] == 'delete':
Target.delete(Target.browse(act[1]))
elif act[0] == 'delete_all':
@@ -169,10 +171,14 @@ class One2Many(Field):
target_ids = map(int, act[1])
if not target_ids:
continue
targets = Target.browse(target_ids)
actions = []
for record_id in ids:
Target.write(Target.browse(target_ids), {
actions.append(targets)
actions.append({
self.field: field_value(record_id),
})
Target.write(*actions)
elif act[0] == 'unlink_all':
targets = Target.search([
search_clause(ids),
@@ -185,18 +191,22 @@ class One2Many(Field):
target_ids = [-1]
else:
target_ids = map(int, act[1])
actions = []
for record_id in ids:
targets = Target.search([
search_clause([record_id]),
('id', 'not in', target_ids),
])
Target.write(targets, {
actions.append(targets)
actions.append({
self.field: None,
})
if act[1]:
Target.write(Target.browse(target_ids), {
actions.append(Target.browse(target_ids))
actions.append({
self.field: field_value(record_id),
})
Target.write(*actions)
elif act[0] == 'copy':
copy_ids = map(int, act[1])
+7 -3
View File
@@ -49,11 +49,15 @@ class ModelSingleton(ModelStorage):
return res
@classmethod
def write(cls, records, values):
def write(cls, records, values, *args):
singleton = cls.get_singleton()
if not singleton:
return cls.create([values])
return super(ModelSingleton, cls).write([singleton], values)
singleton, = cls.create([values])
actions = (records, values) + args
args = []
for values in actions[1:None:2]:
args.extend(([singleton], values))
return super(ModelSingleton, cls).write(*args)
@classmethod
def delete(cls, records):
+67 -64
View File
@@ -629,94 +629,97 @@ class ModelSQL(ModelStorage):
return result
@classmethod
def write(cls, records, values):
def write(cls, records, values, *args):
DatabaseIntegrityError = backend.get('DatabaseIntegrityError')
transaction = Transaction()
cursor = transaction.cursor
pool = Pool()
Translation = pool.get('ir.translation')
Config = pool.get('ir.configuration')
ids = map(int, records)
in_max = cursor.IN_MAX
assert not len(args) % 2
all_records = sum(((records, values) + args)[0:None:2], [])
all_ids = [r.id for r in all_records]
# Call before cursor cache cleaning
trigger_eligibles = cls.trigger_write_get_eligibles(records)
super(ModelSQL, cls).write(records, values)
if not records:
return
super(ModelSQL, cls).write(records, values, *args)
if cls.table_query():
return
table = cls.__table__()
values = values.copy()
cls.__check_timestamp(all_ids)
cls.__check_timestamp(ids)
actions = iter((records, values) + args)
for records, values in zip(actions, actions):
ids = [r.id for r in records]
values = values.copy()
# Clean values
for key in ('create_uid', 'create_date',
'write_uid', 'write_date', 'id'):
if key in values:
del values[key]
# Clean values
for key in ('create_uid', 'create_date',
'write_uid', 'write_date', 'id'):
if key in values:
del values[key]
columns = [table.write_uid, table.write_date]
update_values = [transaction.user, Now()]
store_translation = Transaction().language == Config.get_language()
for fname, value in values.iteritems():
field = cls._fields[fname]
if not hasattr(field, 'set'):
if not getattr(field, 'translate', False) or store_translation:
columns.append(Column(table, fname))
update_values.append(field.sql_format(value))
columns = [table.write_uid, table.write_date]
update_values = [transaction.user, Now()]
store_translation = Transaction().language == Config.get_language()
for fname, value in values.iteritems():
field = cls._fields[fname]
if not hasattr(field, 'set'):
if (not getattr(field, 'translate', False)
or store_translation):
columns.append(Column(table, fname))
update_values.append(field.sql_format(value))
domain = pool.get('ir.rule').domain_get(cls.__name__, mode='write')
for i in range(0, len(ids), in_max):
sub_ids = ids[i:i + in_max]
red_sql = reduce_ids(table.id, sub_ids)
where = red_sql
if domain:
where &= table.id.in_(domain)
cursor.execute(*table.select(table.id, where=where))
rowcount = cursor.rowcount
if rowcount == -1 or rowcount is None:
rowcount = len(cursor.fetchall())
if not rowcount == len({}.fromkeys(sub_ids)):
domain = pool.get('ir.rule').domain_get(cls.__name__, mode='write')
for i in range(0, len(ids), in_max):
sub_ids = ids[i:i + in_max]
red_sql = reduce_ids(table.id, sub_ids)
where = red_sql
if domain:
cursor.execute(*table.select(table.id, where=red_sql))
rowcount = cursor.rowcount
if rowcount == -1 or rowcount is None:
rowcount = len(cursor.fetchall())
if rowcount == len({}.fromkeys(sub_ids)):
cls.raise_user_error('access_error', cls.__name__)
cls.raise_user_error('write_error', cls.__name__)
try:
cursor.execute(*table.update(columns, update_values,
where=red_sql))
except DatabaseIntegrityError, exception:
with contextlib.nested(Transaction().new_cursor(),
Transaction().set_user(0)):
cls.__raise_integrity_error(exception, values,
values.keys())
raise
where &= table.id.in_(domain)
cursor.execute(*table.select(table.id, where=where))
rowcount = cursor.rowcount
if rowcount == -1 or rowcount is None:
rowcount = len(cursor.fetchall())
if not rowcount == len({}.fromkeys(sub_ids)):
if domain:
cursor.execute(*table.select(table.id, where=red_sql))
rowcount = cursor.rowcount
if rowcount == -1 or rowcount is None:
rowcount = len(cursor.fetchall())
if rowcount == len({}.fromkeys(sub_ids)):
cls.raise_user_error('access_error', cls.__name__)
cls.raise_user_error('write_error', cls.__name__)
try:
cursor.execute(*table.update(columns, update_values,
where=red_sql))
except DatabaseIntegrityError, exception:
with contextlib.nested(Transaction().new_cursor(),
Transaction().set_user(0)):
cls.__raise_integrity_error(exception, values,
values.keys())
raise
for fname, value in values.iteritems():
field = cls._fields[fname]
if (getattr(field, 'translate', False)
and not hasattr(field, 'set')):
Translation.set_ids(
'%s,%s' % (cls.__name__, fname), 'model',
transaction.language, ids, [value] * len(ids))
if hasattr(field, 'set'):
field.set(ids, cls, fname, value)
for fname, value in values.iteritems():
field = cls._fields[fname]
if (getattr(field, 'translate', False)
and not hasattr(field, 'set')):
Translation.set_ids(
'%s,%s' % (cls.__name__, fname), 'model',
transaction.language, ids, [value] * len(ids))
if hasattr(field, 'set'):
field.set(ids, cls, fname, value)
cls.__insert_history(ids)
cls._validate(records)
field_names = cls._fields.keys()
cls._update_mptt(field_names, [ids] * len(field_names), values)
field_names = cls._fields.keys()
cls._update_mptt(field_names, [ids] * len(field_names), values)
cls.__insert_history(all_ids)
cls._validate(all_records)
cls.trigger_write(trigger_eligibles)
@classmethod
+14 -7
View File
@@ -53,7 +53,8 @@ class ModelStorage(Model):
'create': RPC(readonly=False,
result=lambda r: map(int, r)),
'read': RPC(),
'write': RPC(readonly=False, instantiate=0),
'write': RPC(readonly=False,
instantiate=slice(0, None, 2)),
'delete': RPC(readonly=False, instantiate=0),
'copy': RPC(readonly=False, instantiate=0,
result=lambda r: map(int, r)),
@@ -126,7 +127,7 @@ class ModelStorage(Model):
return []
@classmethod
def write(cls, records, values):
def write(cls, records, values, *args):
'''
Write values on records.
'''
@@ -137,15 +138,21 @@ class ModelStorage(Model):
ModelAccess.check(cls.__name__, 'write')
ModelFieldAccess.check(cls.__name__,
[x for x in values if x in cls._fields], 'write')
if not cls.check_xml_record(records, values):
cls.raise_user_error('write_xml_record',
error_description='xml_record_desc')
assert not len(args) % 2
actions = iter((records, values) + args)
all_records = []
for records, values in zip(actions, actions):
if not cls.check_xml_record(records, values):
cls.raise_user_error('write_xml_record',
error_description='xml_record_desc')
all_records += records
# Increase transaction counter
Transaction().counter += 1
# Clean local cache
for record in records:
for record in all_records:
local_cache = record._local_cache.get(record.id)
if local_cache:
local_cache.clear()
@@ -153,7 +160,7 @@ class ModelStorage(Model):
# Clean cursor cache
for cache in Transaction().cursor.cache.itervalues():
if cls.__name__ in cache:
for record in records:
for record in all_records:
if record.id in cache[cls.__name__]:
cache[cls.__name__][record.id].clear()
+2 -2
View File
@@ -89,8 +89,8 @@ class Group(ModelSQL, ModelView):
return res
@classmethod
def write(cls, groups, vals):
super(Group, cls).write(groups, vals)
def write(cls, groups, values, *args):
super(Group, cls).write(groups, values, *args)
pool = Pool()
# Restart the cache on the domain_get method
pool.get('ir.rule')._domain_get_cache.clear()
+19 -15
View File
@@ -44,8 +44,8 @@ class UIMenuGroup(ModelSQL):
return res
@classmethod
def write(cls, records, vals):
super(UIMenuGroup, cls).write(records, vals)
def write(cls, records, values, *args):
super(UIMenuGroup, cls).write(records, values, *args)
# Restart the cache on the domain_get method
Pool().get('ir.rule')._domain_get_cache.clear()
@@ -91,12 +91,16 @@ class ActionGroup(ModelSQL):
return res
@classmethod
def write(cls, records, vals):
def write(cls, records, values, *args):
Action = Pool().get('ir.action')
if vals.get('action'):
vals = vals.copy()
vals['action'] = Action.get_action_id(vals['action'])
super(ActionGroup, cls).write(records, vals)
actions = iter((records, values) + args)
args = []
for records, values in zip(actions, actions):
if values.get('action'):
values = values.copy()
values['action'] = Action.get_action_id(values['action'])
args.extend((records, values))
super(ActionGroup, cls).write(*args)
# Restart the cache on the domain_get method
Pool().get('ir.rule')._domain_get_cache.clear()
@@ -153,9 +157,9 @@ class ModelButtonGroup(ModelSQL):
return result
@classmethod
def write(cls, records, values):
def write(cls, records, values, *args):
pool = Pool()
super(ModelButtonGroup, cls).write(records, values)
super(ModelButtonGroup, cls).write(records, values, *args)
# Restart the cache for get_groups
pool.get('ir.model.button')._groups_cache.clear()
@@ -219,8 +223,8 @@ class Lang:
__name__ = 'ir.lang'
@classmethod
def write(cls, langs, vals):
super(Lang, cls).write(langs, vals)
def write(cls, langs, values, *args):
super(Lang, cls).write(langs, values, *args)
# Restart the cache for get_preferences
Pool().get('res.user')._get_preferences_cache.clear()
@@ -256,9 +260,9 @@ class SequenceTypeGroup(ModelSQL):
return res
@classmethod
def write(cls, records, vals):
def write(cls, records, values, *args):
Rule = Pool().get('ir.rule')
super(SequenceTypeGroup, cls).write(records, vals)
super(SequenceTypeGroup, cls).write(records, values, *args)
# Restart the cache on the domain_get method
Rule._domain_get_cache.clear()
@@ -314,10 +318,10 @@ class ModuleConfigWizardItem:
return result
@classmethod
def write(cls, items, values):
def write(cls, items, values, *args):
pool = Pool()
User = pool.get('res.user')
super(ModuleConfigWizardItem, cls).write(items, values)
super(ModuleConfigWizardItem, cls).write(items, values, *args)
# Restart the cache for get_preferences
User._get_preferences_cache.clear()
+15 -7
View File
@@ -211,13 +211,18 @@ class User(ModelSQL, ModelView):
return res
@classmethod
def write(cls, users, vals):
vals = cls._convert_vals(vals)
super(User, cls).write(users, vals)
def write(cls, users, values, *args):
actions = iter((users, values) + args)
all_users = []
args = []
for users, values in zip(actions, actions):
all_users += users
args.extend((users, cls._convert_vals(values)))
super(User, cls).write(*args)
# Clean cursor cache as it could be filled by domain_get
for cache in Transaction().cursor.cache.itervalues():
if cls.__name__ in cache:
for user in users:
for user in all_users:
if user.id in cache[cls.__name__]:
cache[cls.__name__][user.id].clear()
# Restart the cache for domain_get method
@@ -532,9 +537,12 @@ class UserAction(ModelSQL):
return super(UserAction, cls).create(vlist)
@classmethod
def write(cls, records, values):
values = cls._convert_values(values)
super(UserAction, cls).write(records, values)
def write(cls, records, values, *args):
actions = iter((records, values) + args)
args = []
for records, values in zip(actions, actions):
args.extend((records, cls._convert_values(values)))
super(UserAction, cls).write(*args)
class UserGroup(ModelSQL):
+9 -3
View File
@@ -8,7 +8,7 @@ class RPC(object):
'''Define RPC behavior
readonly: The transaction mode
instantiate: The position of the argument to be instanciated
instantiate: The position or the slice of the arguments to be instanciated
result: The function to transform the result
'''
@@ -41,6 +41,12 @@ class RPC(object):
return obj(**data)
else:
return obj.browse(data)
data = args[self.instantiate]
args[self.instantiate] = instance(data)
if isinstance(self.instantiate, slice):
for i, data in enumerate(args[self.instantiate]):
start, _, step = self.instantiate.indices(len(args))
i = i * step + start
args[i] = instance(data)
else:
data = args[self.instantiate]
args[self.instantiate] = instance(data)
return args, kwargs, context, timestamp