Skip to content

Commit d8ead01

Browse files
committed
[IMP] util.update_record_from_xml
Add option to filter the fields to update. closes #227 Signed-off-by: Christophe Simonis (chs) <[email protected]>
1 parent b280073 commit d8ead01

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

src/base/tests/test_util.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,21 @@ def test_update_record_from_xml_bad_match(self):
12581258
tree = etree.fromstring(arch)
12591259
self.assertIsNotNone(tree.find(".//input[@id='login']"))
12601260

1261+
def test_update_record_from_xml__fields(self):
1262+
cr = self.env.cr
1263+
xmlid = "base.USD"
1264+
1265+
usd = self.env.ref(xmlid)
1266+
usd.write({"name": "XXX", "symbol": "¤"})
1267+
util.flush(usd)
1268+
util.invalidate(usd)
1269+
1270+
util.update_record_from_xml(cr, xmlid, fields=("symbol"))
1271+
util.invalidate(usd)
1272+
1273+
self.assertEqual(usd.symbol, "$")
1274+
self.assertEqual(usd.name, "XXX")
1275+
12611276
def test_ensure_xmlid_match_record(self):
12621277
cr = self.env.cr
12631278
tx1 = self.env["res.currency"].create({"name": "TX1", "symbol": "TX1"})

src/util/records.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,7 @@ def update_record_from_xml(
10131013
from_module=None,
10141014
reset_translations=(),
10151015
ensure_references=False,
1016+
fields=None,
10161017
):
10171018
"""
10181019
Update a record based on its definition in the :doc:`/developer/reference/backend/data`.
@@ -1033,6 +1034,8 @@ def update_record_from_xml(
10331034
:param set(str) reset_translations: field names whose translations get reset
10341035
:param bool ensure_references: whether referred records via `ref` XML attributes
10351036
should also be updated.
1037+
:param set(str) or None fields: optional list of fields to include in the XML declaration.
1038+
If set, all other fields will be ignored.
10361039
10371040
.. warning::
10381041
This functions uses the ORM, therefore it can only be used after **all** models
@@ -1051,6 +1054,7 @@ def update_record_from_xml(
10511054
from_module=from_module,
10521055
reset_translations=reset_translations,
10531056
ensure_references=ensure_references,
1057+
fields=fields,
10541058
done_refs=set(),
10551059
)
10561060

@@ -1063,11 +1067,11 @@ def __update_record_from_xml(
10631067
from_module,
10641068
reset_translations,
10651069
ensure_references,
1070+
fields,
10661071
done_refs,
10671072
):
10681073
from .modules import get_manifest
10691074

1070-
# Force update of a record from xml file to bypass the noupdate flag
10711075
if "." not in xmlid:
10721076
raise ValueError("Please use fully qualified name <module>.<name>")
10731077

@@ -1095,6 +1099,7 @@ def __update_record_from_xml(
10951099
else:
10961100
# The xmlid doesn't already exists, nothing to reset
10971101
reset_write_metadata = noupdate = reset_translations = False
1102+
fields = None
10981103

10991104
write_data = None
11001105
if reset_write_metadata:
@@ -1133,6 +1138,10 @@ def add_ref(ref):
11331138
for node in doc.xpath(xpath):
11341139
found = True
11351140
parent = node.getparent()
1141+
if node.tag == "record" and fields is not None:
1142+
for fn in node.xpath("./field[@name]"):
1143+
if fn.attrib["name"] not in fields:
1144+
node.remove(fn)
11361145
new_root[0].append(node)
11371146

11381147
if node.tag == "menuitem" and parent.tag == "menuitem" and "parent_id" not in node.attrib:
@@ -1148,8 +1157,12 @@ def add_ref(ref):
11481157
template = True
11491158
if ensure_references:
11501159
for ref_node in node.xpath("//field[@ref]"):
1160+
if fields is not None and ref_node.attrib["name"] not in fields:
1161+
continue
11511162
add_ref(ref_node.get("ref"))
11521163
for eval_node in node.xpath("//field[@eval]"):
1164+
if fields is not None and eval_node.attrib["name"] not in fields:
1165+
continue
11531166
for ref_match in re.finditer(r"\bref\((['\"])(.*?)\1\)", eval_node.get("eval")):
11541167
add_ref(ref_match.group(2))
11551168

@@ -1172,6 +1185,7 @@ def add_ref(ref):
11721185
from_module=from_module,
11731186
reset_translations=reset_translations,
11741187
ensure_references=True,
1188+
fields=None,
11751189
done_refs=done_refs,
11761190
)
11771191

@@ -1189,9 +1203,12 @@ def add_ref(ref):
11891203

11901204
if reset_translations:
11911205
if reset_translations is True:
1192-
fields_with_values_from_xml = {elem.attrib["name"] for elem in node.xpath("//record/field")}
1193-
if template:
1194-
fields_with_values_from_xml |= {"arch_db", "name"}
1206+
if fields is None:
1207+
fields_with_values_from_xml = {elem.attrib["name"] for elem in node.xpath("//record/field")}
1208+
if template:
1209+
fields_with_values_from_xml |= {"arch_db", "name"}
1210+
else:
1211+
fields_with_values_from_xml = fields
11951212
cr.execute(
11961213
"SELECT name FROM ir_model_fields WHERE model = %s AND translate = true AND name IN %s",
11971214
[model, tuple(fields_with_values_from_xml)],

0 commit comments

Comments
 (0)