[FIX]:_inherits for multilevel inheritence
lp bug: https://launchpad.net/bugs/823691 fixed bzr revid: nch@tinyerp.com-20110826103516-o220jqwqdr3uwjhn
This commit is contained in:
parent
eba378a4d6
commit
8d0cf999ac
|
@ -53,7 +53,7 @@ def _symbol_set(symb):
|
||||||
|
|
||||||
class _column(object):
|
class _column(object):
|
||||||
""" Base of all fields, a database column
|
""" Base of all fields, a database column
|
||||||
|
|
||||||
An instance of this object is a *description* of a database column. It will
|
An instance of this object is a *description* of a database column. It will
|
||||||
not hold any data, but only provide the methods to manipulate data of an
|
not hold any data, but only provide the methods to manipulate data of an
|
||||||
ORM record or even prepare/update the database to hold such a field of data.
|
ORM record or even prepare/update the database to hold such a field of data.
|
||||||
|
@ -1285,7 +1285,7 @@ class property(function):
|
||||||
|
|
||||||
def _fnct_read(self, obj, cr, uid, ids, prop_names, obj_dest, context=None):
|
def _fnct_read(self, obj, cr, uid, ids, prop_names, obj_dest, context=None):
|
||||||
prop = obj.pool.get('ir.property')
|
prop = obj.pool.get('ir.property')
|
||||||
# get the default values (for res_id = False) for the property fields
|
# get the default values (for res_id = False) for the property fields
|
||||||
default_val = self._get_defaults(obj, cr, uid, prop_names, context)
|
default_val = self._get_defaults(obj, cr, uid, prop_names, context)
|
||||||
|
|
||||||
# build the dictionary that will be returned
|
# build the dictionary that will be returned
|
||||||
|
@ -1407,12 +1407,16 @@ class column_info(object):
|
||||||
:attr parent_column: the name of the column containing the m2o
|
:attr parent_column: the name of the column containing the m2o
|
||||||
relationship to the parent model that contains
|
relationship to the parent model that contains
|
||||||
this column, None for local columns.
|
this column, None for local columns.
|
||||||
|
:attr original_parent: if the column is inherited, name of the original
|
||||||
|
parent model that contains it i.e in case of multilevel
|
||||||
|
inheritence, None for local columns.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, column, parent_model=None, parent_column=None):
|
def __init__(self, name, column, parent_model=None, parent_column=None, original_parent=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.column = column
|
self.column = column
|
||||||
self.parent_model = parent_model
|
self.parent_model = parent_model
|
||||||
self.parent_column = parent_column
|
self.parent_column = parent_column
|
||||||
|
self.original_parent = original_parent
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
- classicals (varchar, integer, boolean, ...)
|
- classicals (varchar, integer, boolean, ...)
|
||||||
- relations (one2many, many2one, many2many)
|
- relations (one2many, many2one, many2many)
|
||||||
- functions
|
- functions
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import calendar
|
import calendar
|
||||||
|
@ -168,7 +168,7 @@ def modifiers_tests():
|
||||||
test_modifiers({}, '{}')
|
test_modifiers({}, '{}')
|
||||||
test_modifiers({"invisible": True}, '{"invisible": true}')
|
test_modifiers({"invisible": True}, '{"invisible": true}')
|
||||||
test_modifiers({"invisible": False}, '{}')
|
test_modifiers({"invisible": False}, '{}')
|
||||||
|
|
||||||
|
|
||||||
def check_object_name(name):
|
def check_object_name(name):
|
||||||
""" Check if the given name is a valid openerp object name.
|
""" Check if the given name is a valid openerp object name.
|
||||||
|
@ -255,7 +255,7 @@ class browse_null(object):
|
||||||
#
|
#
|
||||||
class browse_record_list(list):
|
class browse_record_list(list):
|
||||||
""" Collection of browse objects
|
""" Collection of browse objects
|
||||||
|
|
||||||
Such an instance will be returned when doing a ``browse([ids..])``
|
Such an instance will be returned when doing a ``browse([ids..])``
|
||||||
and will be iterable, yielding browse() objects
|
and will be iterable, yielding browse() objects
|
||||||
"""
|
"""
|
||||||
|
@ -270,9 +270,9 @@ class browse_record_list(list):
|
||||||
class browse_record(object):
|
class browse_record(object):
|
||||||
""" An object that behaves like a row of an object's table.
|
""" An object that behaves like a row of an object's table.
|
||||||
It has attributes after the columns of the corresponding object.
|
It has attributes after the columns of the corresponding object.
|
||||||
|
|
||||||
Examples::
|
Examples::
|
||||||
|
|
||||||
uobj = pool.get('res.users')
|
uobj = pool.get('res.users')
|
||||||
user_rec = uobj.browse(cr, uid, 104)
|
user_rec = uobj.browse(cr, uid, 104)
|
||||||
name = user_rec.name
|
name = user_rec.name
|
||||||
|
@ -1093,7 +1093,7 @@ class orm_template(object):
|
||||||
if line[i] and skip:
|
if line[i] and skip:
|
||||||
return False
|
return False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
#set the mode for m2o, o2m, m2m : xml_id/id/name
|
#set the mode for m2o, o2m, m2m : xml_id/id/name
|
||||||
if len(field) == len(prefix)+1:
|
if len(field) == len(prefix)+1:
|
||||||
mode = False
|
mode = False
|
||||||
|
@ -1106,7 +1106,7 @@ class orm_template(object):
|
||||||
for db_id in line.split(config.get('csv_internal_sep')):
|
for db_id in line.split(config.get('csv_internal_sep')):
|
||||||
res.append(_get_id(relation, db_id, current_module, mode))
|
res.append(_get_id(relation, db_id, current_module, mode))
|
||||||
return [(6,0,res)]
|
return [(6,0,res)]
|
||||||
|
|
||||||
# ID of the record using a XML ID
|
# ID of the record using a XML ID
|
||||||
if field[len(prefix)]=='id':
|
if field[len(prefix)]=='id':
|
||||||
try:
|
try:
|
||||||
|
@ -1130,9 +1130,9 @@ class orm_template(object):
|
||||||
relation_obj = self.pool.get(relation)
|
relation_obj = self.pool.get(relation)
|
||||||
newfd = relation_obj.fields_get( cr, uid, context=context )
|
newfd = relation_obj.fields_get( cr, uid, context=context )
|
||||||
pos = position
|
pos = position
|
||||||
|
|
||||||
res = many_ids(line[i], relation, current_module, mode)
|
res = many_ids(line[i], relation, current_module, mode)
|
||||||
|
|
||||||
first = 0
|
first = 0
|
||||||
while pos < len(datas):
|
while pos < len(datas):
|
||||||
res2 = process_liness(self, datas, prefix + [field[len(prefix)]], current_module, relation_obj._name, newfd, pos, first)
|
res2 = process_liness(self, datas, prefix + [field[len(prefix)]], current_module, relation_obj._name, newfd, pos, first)
|
||||||
|
@ -1142,15 +1142,15 @@ class orm_template(object):
|
||||||
nbrmax = max(nbrmax, pos)
|
nbrmax = max(nbrmax, pos)
|
||||||
warning += w2
|
warning += w2
|
||||||
first += 1
|
first += 1
|
||||||
|
|
||||||
if data_res_id2:
|
if data_res_id2:
|
||||||
res.append((4, data_res_id2))
|
res.append((4, data_res_id2))
|
||||||
|
|
||||||
if (not newrow) or not reduce(lambda x, y: x or y, newrow.values(), 0):
|
if (not newrow) or not reduce(lambda x, y: x or y, newrow.values(), 0):
|
||||||
break
|
break
|
||||||
|
|
||||||
res.append( (data_res_id2 and 1 or 0, data_res_id2 or 0, newrow) )
|
res.append( (data_res_id2 and 1 or 0, data_res_id2 or 0, newrow) )
|
||||||
|
|
||||||
|
|
||||||
elif fields_def[field[len(prefix)]]['type']=='many2one':
|
elif fields_def[field[len(prefix)]]['type']=='many2one':
|
||||||
relation = fields_def[field[len(prefix)]]['relation']
|
relation = fields_def[field[len(prefix)]]['relation']
|
||||||
|
@ -1179,7 +1179,7 @@ class orm_template(object):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
res = line[i]
|
res = line[i]
|
||||||
|
|
||||||
row[field[len(prefix)]] = res or False
|
row[field[len(prefix)]] = res or False
|
||||||
|
|
||||||
result = (row, nbrmax, warning, data_res_id, xml_id)
|
result = (row, nbrmax, warning, data_res_id, xml_id)
|
||||||
|
@ -1193,7 +1193,7 @@ class orm_template(object):
|
||||||
position = 0
|
position = 0
|
||||||
while position<len(datas):
|
while position<len(datas):
|
||||||
res = {}
|
res = {}
|
||||||
|
|
||||||
(res, position, warning, res_id, xml_id) = \
|
(res, position, warning, res_id, xml_id) = \
|
||||||
process_liness(self, datas, [], current_module, self._name, fields_def, position=position)
|
process_liness(self, datas, [], current_module, self._name, fields_def, position=position)
|
||||||
if len(warning):
|
if len(warning):
|
||||||
|
@ -1560,7 +1560,7 @@ class orm_template(object):
|
||||||
field = model_fields.get(node.get('name'))
|
field = model_fields.get(node.get('name'))
|
||||||
if field:
|
if field:
|
||||||
transfer_field_to_modifiers(field, modifiers)
|
transfer_field_to_modifiers(field, modifiers)
|
||||||
|
|
||||||
|
|
||||||
elif node.tag in ('form', 'tree'):
|
elif node.tag in ('form', 'tree'):
|
||||||
result = self.view_header_get(cr, user, False, node.tag, context)
|
result = self.view_header_get(cr, user, False, node.tag, context)
|
||||||
|
@ -2609,20 +2609,22 @@ class orm(orm_template):
|
||||||
del d['id']
|
del d['id']
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _inherits_join_add(self, parent_model_name, query):
|
def _inherits_join_add(self, current_table, parent_model_name, query):
|
||||||
"""
|
"""
|
||||||
Add missing table SELECT and JOIN clause to ``query`` for reaching the parent table (no duplicates)
|
Add missing table SELECT and JOIN clause to ``query`` for reaching the parent table (no duplicates)
|
||||||
|
:param current_table: current model object
|
||||||
:param parent_model_name: name of the parent model for which the clauses should be added
|
:param parent_model_name: name of the parent model for which the clauses should be added
|
||||||
:param query: query object on which the JOIN should be added
|
:param query: query object on which the JOIN should be added
|
||||||
"""
|
"""
|
||||||
inherits_field = self._inherits[parent_model_name]
|
inherits_field = current_table._inherits[parent_model_name]
|
||||||
parent_model = self.pool.get(parent_model_name)
|
parent_model = self.pool.get(parent_model_name)
|
||||||
parent_table_name = parent_model._table
|
parent_table_name = parent_model._table
|
||||||
quoted_parent_table_name = '"%s"' % parent_table_name
|
quoted_parent_table_name = '"%s"' % parent_table_name
|
||||||
if quoted_parent_table_name not in query.tables:
|
if quoted_parent_table_name not in query.tables:
|
||||||
query.tables.append(quoted_parent_table_name)
|
query.tables.append(quoted_parent_table_name)
|
||||||
query.where_clause.append('("%s".%s = %s.id)' % (self._table, inherits_field, parent_table_name))
|
query.where_clause.append('(%s.%s = %s.id)' % (current_table._table, inherits_field, parent_table_name))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _inherits_join_calc(self, field, query):
|
def _inherits_join_calc(self, field, query):
|
||||||
"""
|
"""
|
||||||
|
@ -2637,7 +2639,7 @@ class orm(orm_template):
|
||||||
while field in current_table._inherit_fields and not field in current_table._columns:
|
while field in current_table._inherit_fields and not field in current_table._columns:
|
||||||
parent_model_name = current_table._inherit_fields[field][0]
|
parent_model_name = current_table._inherit_fields[field][0]
|
||||||
parent_table = self.pool.get(parent_model_name)
|
parent_table = self.pool.get(parent_model_name)
|
||||||
self._inherits_join_add(parent_model_name, query)
|
self._inherits_join_add(current_table, parent_model_name, query)
|
||||||
current_table = parent_table
|
current_table = parent_table
|
||||||
return '"%s".%s' % (current_table._table, field)
|
return '"%s".%s' % (current_table._table, field)
|
||||||
|
|
||||||
|
@ -3328,9 +3330,9 @@ class orm(orm_template):
|
||||||
for table in self._inherits:
|
for table in self._inherits:
|
||||||
other = self.pool.get(table)
|
other = self.pool.get(table)
|
||||||
for col in other._columns.keys():
|
for col in other._columns.keys():
|
||||||
res[col] = (table, self._inherits[table], other._columns[col])
|
res[col] = (table, self._inherits[table], other._columns[col], table)
|
||||||
for col in other._inherit_fields.keys():
|
for col in other._inherit_fields.keys():
|
||||||
res[col] = (table, self._inherits[table], other._inherit_fields[col][2])
|
res[col] = (table, self._inherits[table], other._inherit_fields[col][2], other._inherit_fields[col][3])
|
||||||
self._inherit_fields = res
|
self._inherit_fields = res
|
||||||
self._all_columns = self._get_column_infos()
|
self._all_columns = self._get_column_infos()
|
||||||
self._inherits_reload_src()
|
self._inherits_reload_src()
|
||||||
|
@ -3341,8 +3343,8 @@ class orm(orm_template):
|
||||||
inherited field via _inherits) to a ``column_info`` struct
|
inherited field via _inherits) to a ``column_info`` struct
|
||||||
giving detailed columns """
|
giving detailed columns """
|
||||||
result = {}
|
result = {}
|
||||||
for k, (parent, m2o, col) in self._inherit_fields.iteritems():
|
for k, (parent, m2o, col, original_parent) in self._inherit_fields.iteritems():
|
||||||
result[k] = fields.column_info(k, col, parent, m2o)
|
result[k] = fields.column_info(k, col, parent, m2o, original_parent)
|
||||||
for k, col in self._columns.iteritems():
|
for k, col in self._columns.iteritems():
|
||||||
result[k] = fields.column_info(k, col)
|
result[k] = fields.column_info(k, col)
|
||||||
return result
|
return result
|
||||||
|
@ -4373,7 +4375,7 @@ class orm(orm_template):
|
||||||
if parent_model and child_object:
|
if parent_model and child_object:
|
||||||
# as inherited rules are being applied, we need to add the missing JOIN
|
# as inherited rules are being applied, we need to add the missing JOIN
|
||||||
# to reach the parent table (if it was not JOINed yet in the query)
|
# to reach the parent table (if it was not JOINed yet in the query)
|
||||||
child_object._inherits_join_add(parent_model, query)
|
child_object._inherits_join_add(child_object, parent_model, query)
|
||||||
query.where_clause += added_clause
|
query.where_clause += added_clause
|
||||||
query.where_clause_params += added_params
|
query.where_clause_params += added_params
|
||||||
for table in added_tables:
|
for table in added_tables:
|
||||||
|
@ -4462,7 +4464,7 @@ class orm(orm_template):
|
||||||
else:
|
else:
|
||||||
continue # ignore non-readable or "non-joinable" fields
|
continue # ignore non-readable or "non-joinable" fields
|
||||||
elif order_field in self._inherit_fields:
|
elif order_field in self._inherit_fields:
|
||||||
parent_obj = self.pool.get(self._inherit_fields[order_field][0])
|
parent_obj = self.pool.get(self._inherit_fields[order_field][3])
|
||||||
order_column = parent_obj._columns[order_field]
|
order_column = parent_obj._columns[order_field]
|
||||||
if order_column._classic_read:
|
if order_column._classic_read:
|
||||||
inner_clause = self._inherits_join_calc(order_field, query)
|
inner_clause = self._inherits_join_calc(order_field, query)
|
||||||
|
|
Loading…
Reference in New Issue