Use a sequence of ids, values to set fields

review3331003
This commit is contained in:
Cédric Krier
2014-02-24 19:15:57 +01:00
parent 275e612288
commit 2680d1b746
7 changed files with 129 additions and 98 deletions
+1
View File
@@ -1,3 +1,4 @@
* Use a sequence of ids, values to set fields
* Client side actions on button and wizard
* Add depends attribute to data tag
* Add tree_invisible attribute to button in tree view
+6 -2
View File
@@ -91,12 +91,16 @@ class Function(Field):
name = [name]
return call(name)
def set(self, ids, Model, name, value):
def set(self, Model, name, ids, value, *args):
'''
Call the setter.
'''
if self.setter:
getattr(Model, self.setter)(Model.browse(ids), name, value)
# TODO change setter API to use sequence of records, value
setter = getattr(Model, self.setter)
args = iter((ids, value) + args)
for ids, value in zip(args, args):
setter(Model.browse(ids), name, value)
def __set__(self, inst, value):
self._field.__set__(inst, value)
+38 -33
View File
@@ -95,7 +95,7 @@ class Many2Many(Field):
res[origin_id].append(getattr(relation, self.target).id)
return dict((key, tuple(value)) for key, value in res.iteritems())
def set(self, ids, model, name, values):
def set(self, Model, name, ids, values, *args):
'''
Set the values.
@@ -113,40 +113,41 @@ class Many2Many(Field):
Relation = pool.get(self.relation_name)
Target = self.get_target()
origin_field = Relation._fields[self.origin]
relation_to_create = []
relation_to_delete = []
target_to_write = []
target_to_delete = []
def search_clause(ids):
if origin_field._type == 'reference':
references = ['%s,%s' % (model.__name__, x) for x in ids]
references = ['%s,%s' % (Model.__name__, x) for x in ids]
return (self.origin, 'in', references)
else:
return (self.origin, 'in', ids)
def field_value(record_id):
if origin_field._type == 'reference':
return '%s,%s' % (model.__name__, record_id)
return '%s,%s' % (Model.__name__, record_id)
else:
return record_id
def create(vlist):
to_create = []
def create(ids, vlist):
for record_id in ids:
for new in Target.create(vlist):
to_create.append({
relation_to_create.append({
self.origin: field_value(record_id),
self.target: new.id,
})
if to_create:
Relation.create(to_create)
def write(*args):
def write(_, *args):
actions = iter(args)
Target.write(*sum(((Target.browse(ids), values)
target_to_write.extend(sum(((Target.browse(ids), values)
for ids, values in zip(actions, actions)), ()))
def delete(target_ids):
Target.delete(Target.browse(target_ids))
def delete(_, target_ids):
target_to_delete.extend(Target.browse(target_ids))
def add(target_ids):
def add(ids, target_ids):
target_ids = map(int, target_ids)
if not target_ids:
return
@@ -160,48 +161,40 @@ class Many2Many(Field):
])
for relation in relations:
existing_ids.add(getattr(relation, self.target).id)
to_create = []
for new_id in target_ids:
if new_id in existing_ids:
continue
for record_id in ids:
to_create.append({
relation_to_create.append({
self.origin: field_value(record_id),
self.target: new_id,
})
if to_create:
Relation.create(to_create)
def remove(target_ids):
def remove(ids, target_ids):
target_ids = map(int, target_ids)
if not target_ids:
return
relations = []
in_max = Transaction().cursor.IN_MAX
for i in range(0, len(target_ids), in_max):
sub_ids = target_ids[i:i + in_max]
relations += Relation.search([
search_clause(ids),
(self.target, 'in', sub_ids),
])
Relation.delete(relations)
relation_to_delete.extend(Relation.search([
search_clause(ids),
(self.target, 'in', sub_ids),
]))
def copy(copy_ids, default=None):
def copy(ids, copy_ids, default=None):
copy_ids = map(int, copy_ids)
if default is None:
default = {}
default = default.copy()
to_create = []
copies = Target.browse(copy_ids)
for new in Target.copy(copies, default=default):
for record_id in ids:
to_create.append({
relation_to_create.append({
self.origin: field_value(record_id),
self.target: new.id,
})
if to_create:
Relation.create(to_create)
actions = {
'create': create,
@@ -211,10 +204,22 @@ class Many2Many(Field):
'remove': remove,
'copy': copy,
}
for value in values:
action = value[0]
args = value[1:]
actions[action](*args)
args = iter((ids, values) + args)
for ids, values in zip(args, args):
if not values:
continue
for value in values:
action = value[0]
args = value[1:]
actions[action](ids, *args)
if relation_to_create:
Relation.create(relation_to_create)
if relation_to_delete:
Relation.delete(relation_to_delete)
if target_to_write:
Target.write(*target_to_write)
if target_to_delete:
Target.delete(target_to_delete)
def get_target(self):
'Return the target model'
+41 -30
View File
@@ -102,7 +102,7 @@ class One2Many(Field):
res[origin_id].append(target.id)
return dict((key, tuple(value)) for key, value in res.iteritems())
def set(self, ids, model, name, values):
def set(self, Model, name, ids, values, *args):
'''
Set the values.
values: A list of tuples:
@@ -113,66 +113,67 @@ class One2Many(Field):
(``remove``, ``<ids>``),
(``copy``, ``<ids>``, ``[{<field name>: value}, ...]``)
'''
if not values:
return
Target = self.get_target()
field = Target._fields[self.field]
to_create = []
to_write = []
to_delete = []
def search_clause(ids):
if field._type == 'reference':
references = ['%s,%s' % (model.__name__, x) for x in ids]
references = ['%s,%s' % (Model.__name__, x) for x in ids]
return (self.field, 'in', references)
else:
return (self.field, 'in', ids)
def field_value(record_id):
if field._type == 'reference':
return '%s,%s' % (model.__name__, record_id)
return '%s,%s' % (Model.__name__, record_id)
else:
return record_id
def create(vlist):
to_create = []
def create(ids, vlist):
for record_id in ids:
value = field_value(record_id)
for values in vlist:
values = values.copy()
values[self.field] = value
to_create.append(values)
if to_create:
Target.create(to_create)
def write(*args):
def write(_, *args):
actions = iter(args)
Target.write(*sum(((Target.browse(ids), values)
to_write.extend(sum(((Target.browse(ids), values)
for ids, values in zip(actions, actions)), ()))
def delete(target_ids):
Target.delete(Target.browse(target_ids))
def delete(_, target_ids):
to_delete.extend(Target.browse(target_ids))
def add(target_ids):
def add(ids, target_ids):
target_ids = map(int, target_ids)
if not target_ids:
return
targets = Target.browse(target_ids)
for record_id in ids:
Target.write(targets, {
self.field: field_value(record_id),
})
to_write.extend((targets, {
self.field: field_value(record_id),
}))
def remove(target_ids):
def remove(ids, target_ids):
target_ids = map(int, target_ids)
if not target_ids:
return
targets = Target.search([
search_clause(ids),
('id', 'in', target_ids),
])
Target.write(targets, {
self.field: None,
})
in_max = Transaction().cursor.IN_MAX
for i in range(0, len(target_ids), in_max):
sub_ids = target_ids[i:i + in_max]
targets = Target.search([
search_clause(ids),
('id', 'in', sub_ids),
])
to_write.extend((targets, {
self.field: None,
}))
def copy(copy_ids, default=None):
def copy(ids, copy_ids, default=None):
copy_ids = map(int, copy_ids)
if default is None:
@@ -191,10 +192,20 @@ class One2Many(Field):
'remove': remove,
'copy': copy,
}
for value in values:
action = value[0]
args = value[1:]
actions[action](*args)
args = iter((ids, values) + args)
for ids, values in zip(args, args):
if not values:
continue
for value in values:
action = value[0]
args = value[1:]
actions[action](ids, *args)
if to_create:
Target.create(to_create)
if to_write:
Target.write(*to_write)
if to_delete:
Target.delete(to_delete)
def get_target(self):
'Return the target Model'
+20 -19
View File
@@ -28,30 +28,31 @@ class One2One(Many2Many):
res[i] = vals[0] if vals else False
return res
def set(self, ids, model, name, value):
def set(self, Model, name, ids, value, *args):
'''
Set the values.
:param ids: A list of ids
:param model: A string with the name of the model
:param name: A string with the name of the field
:param value: The id to link
'''
pool = Pool()
Relation = pool.get(self.relation_name)
relations = Relation.search([
(self.origin, 'in', ids),
])
Relation.delete(relations)
if value:
to_create = []
for record_id in ids:
to_create.append({
self.origin: record_id,
self.target: value,
})
if to_create:
Relation.create(to_create)
to_delete = []
to_create = []
args = iter((ids, value) + args)
for ids, value in zip(args, args):
relations = Relation.search([
(self.origin, 'in', ids),
])
to_delete.extend(relations)
if value:
to_create = []
for record_id in ids:
to_create.append({
self.origin: record_id,
self.target: value,
})
if to_delete:
Relation.delete(to_delete)
if to_create:
Relation.create(to_create)
def __set__(self, inst, value):
Target = self.get_target()
+10 -12
View File
@@ -46,23 +46,21 @@ class Property(Function):
Property = pool.get('ir.property')
return Property.get(name, model.__name__, ids)
def set(self, ids, model, name, value):
def set(self, Model, name, ids, value, *args):
'''
Set the property.
:param ids: A list of ids.
:param model: The model.
:param name: The name of the field.
:param value: The value to set.
'''
pool = Pool()
Property = pool.get('ir.property')
if value is not None:
prop_value = '%s,%s' % (getattr(self, 'model_name', ''),
str(value))
else:
prop_value = None
Property.set(name, model.__name__, ids, prop_value)
args = iter((ids, value) + args)
for ids, value in zip(args, args):
if value is not None:
prop_value = '%s,%s' % (getattr(self, 'model_name', ''),
str(value))
else:
prop_value = None
# TODO change set API to use sequence of records, value
Property.set(name, Model.__name__, ids, prop_value)
def convert_domain(self, domain, tables, Model):
pool = Pool()
+13 -2
View File
@@ -379,6 +379,7 @@ class ModelSQL(ModelStorage):
set()).update(new_ids)
translation_values = {}
fields_to_set = {}
for values, new_id in izip(vlist, new_ids):
for fname, value in values.iteritems():
field = cls._fields[fname]
@@ -387,13 +388,18 @@ class ModelSQL(ModelStorage):
translation_values.setdefault(
'%s,%s' % (cls.__name__, fname), {})[new_id] = value
if hasattr(field, 'set'):
field.set([new_id], cls, fname, value)
fields_to_set.setdefault(fname, []).extend(
([new_id], value))
if translation_values:
for name, translations in translation_values.iteritems():
Translation.set_ids(name, 'model', Transaction().language,
translations.keys(), translations.values())
for fname, fargs in fields_to_set.iteritems():
field = cls._fields[fname]
field.set(cls, fname, *fargs)
cls.__insert_history(new_ids)
records = cls.browse(new_ids)
@@ -657,6 +663,7 @@ class ModelSQL(ModelStorage):
cls.__check_timestamp(all_ids)
fields_to_set = {}
actions = iter((records, values) + args)
for records, values in zip(actions, actions):
ids = [r.id for r in records]
@@ -717,12 +724,16 @@ class ModelSQL(ModelStorage):
'%s,%s' % (cls.__name__, fname), 'model',
transaction.language, ids, [value] * len(ids))
if hasattr(field, 'set'):
field.set(ids, cls, fname, value)
fields_to_set.setdefault(fname, []).extend((ids, value))
field_names = cls._fields.keys()
cls._update_mptt(field_names, [ids] * len(field_names), values)
all_field_names |= set(values.keys())
for fname, fargs in fields_to_set.iteritems():
field = cls._fields[fname]
field.set(cls, fname, *fargs)
cls.__insert_history(all_ids)
for i in range(0, len(all_records), RECORD_CACHE_SIZE):
cls._validate(all_records[i:i + RECORD_CACHE_SIZE],