Use a sequence of ids, values to set fields
review3331003
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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],
|
||||
|
||||
Reference in New Issue
Block a user