[FIX] base, web: don't fold M2M when not in import compatible mode
Before this commit, if the first exported field of an M2M is `id` (the xid) the entire M2M is folded into a single cell with comma-separated xids and any following field is ignored. If `id` is any but the first field, the export behaves normally (with the m2m exported as a "table" inside the parent record). This behaviour makes sense for import-compatible exports where the id is the only thing which can be exported anyway, but it is troublesome outside of that mode as the behaviour of m2m under export becomes incoherent/unpredictable (ish) as it depends on the position of the m2m's `id` in the exports list. Change it so we only perform folding in import-compatible mode (which is the default for backwards compatibility with e.g. API calling export_data directly & the like). opw-813361 Fixes #22600
This commit is contained in:
committed by
Nicolas Martinelli
parent
906a9af8f2
commit
a583a56324
@@ -1335,7 +1335,7 @@ class ExportFormat(object):
|
||||
model, fields, ids, domain, import_compat = \
|
||||
operator.itemgetter('model', 'fields', 'ids', 'domain', 'import_compat')(params)
|
||||
|
||||
Model = request.env[model].with_context(**params.get('context', {}))
|
||||
Model = request.env[model].with_context(import_compat=import_compat, **params.get('context', {}))
|
||||
records = Model.browse(ids) or Model.search(domain, offset=0, limit=False, order=False)
|
||||
|
||||
if not Model._is_an_ordinary_table():
|
||||
|
||||
@@ -600,7 +600,54 @@ class test_m2m(CreatorCase):
|
||||
['', u'export.many2many.other:13'],
|
||||
])
|
||||
|
||||
# essentially same as o2m, so boring
|
||||
def test_multiple_records_subfield(self):
|
||||
r = self.make(self.commands)
|
||||
xid = self.env['ir.model.data'].create({
|
||||
'name': 'whopwhopwhop',
|
||||
'module': '__t__',
|
||||
'model': r._name,
|
||||
'res_id': r.id,
|
||||
}).complete_name
|
||||
sids = [
|
||||
self.env['ir.model.data'].create({
|
||||
'name': sub.str,
|
||||
'module': '__t__',
|
||||
'model': sub._name,
|
||||
'res_id': sub.id,
|
||||
}).complete_name
|
||||
for sub in r.value
|
||||
]
|
||||
r.invalidate_cache()
|
||||
|
||||
self.assertEqual(
|
||||
r._export_rows([['value', 'id']]),
|
||||
[['__t__.record000,__t__.record001,__t__.record010,__t__.record011,__t__.record100']]
|
||||
)
|
||||
self.assertEqual(
|
||||
r.with_context(import_compat=True)._export_rows([['value', 'id']]),
|
||||
[['__t__.record000,__t__.record001,__t__.record010,__t__.record011,__t__.record100']]
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
r.with_context(import_compat=False)._export_rows([['id'], ['value', 'id'], ['value', 'value']]),
|
||||
[
|
||||
[xid, u'__t__.record000', u'4'],
|
||||
[u'', u'__t__.record001', u'42'],
|
||||
[u'', u'__t__.record010', u'36'],
|
||||
[u'', u'__t__.record011', u'4'],
|
||||
[u'', u'__t__.record100', u'13']
|
||||
]
|
||||
)
|
||||
self.assertEqual(
|
||||
r.with_context(import_compat=False)._export_rows([['id'], ['value', 'value'], ['value', 'id']]),
|
||||
[
|
||||
[xid, u'4', u'__t__.record000'],
|
||||
[u'', u'42', u'__t__.record001'],
|
||||
[u'', u'36', u'__t__.record010'],
|
||||
[u'', u'4', u'__t__.record011'],
|
||||
[u'', u'13', u'__t__.record100']
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class test_function(CreatorCase):
|
||||
|
||||
+4
-2
@@ -758,6 +758,7 @@ class BaseModel(object):
|
||||
:param fields: list of lists of fields to traverse
|
||||
:return: list of lists of corresponding values
|
||||
"""
|
||||
import_compatible = self.env.context.get('import_compat', True)
|
||||
lines = []
|
||||
for record in self:
|
||||
# main line of record, initially empty
|
||||
@@ -791,8 +792,9 @@ class BaseModel(object):
|
||||
else:
|
||||
primary_done.append(name)
|
||||
|
||||
# This is a special case, its strange behavior is intended!
|
||||
if field.type == 'many2many' and len(path) > 1 and path[1] == 'id':
|
||||
# in import_compat mode, m2m should always be exported as
|
||||
# a comma-separated list of xids in a single cell
|
||||
if import_compatible and field.type == 'many2many' and len(path) > 1 and path[1] == 'id':
|
||||
xml_ids = [r.__export_xml_id() for r in value]
|
||||
current[i] = ','.join(xml_ids) or False
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user