[ADD] jsonifier: with_fieldname option

Orig commit msg:

[ADD] use jsonifier features to retund postprocessed values, containing
field string as well

Better Version, not using function features , leaves parser syntax
intact.

[FIX] Review fixes

[FIX] small comment and style fix
pull/3205/head
Giovanni Francesco Capalbo 2023-09-19 17:57:32 +02:00 committed by Simone Orsi
parent 908a4c5956
commit aee47a5e41
3 changed files with 99 additions and 5 deletions

View File

@ -103,6 +103,13 @@ class Base(models.AbstractModel):
value, json_key = self._jsonify_record_handle_resolver(
rec, field, resolver, json_key
)
# whatever json value we have found in subparser or not ass a sister key
# on the same level _fieldname_{json_key}
if rec.env.context.get("with_fieldname"):
json_key_fieldname = "_fieldname_" + json_key
# check if we are in a subparser has already the fieldname sister keys
fieldname_value = rec._fields[field_dict["name"]].string
self._add_json_key(root, json_key_fieldname, fieldname_value)
self._add_json_key(root, json_key, value)
return root
@ -150,10 +157,11 @@ class Base(models.AbstractModel):
{"model": self._name, "fname": field_name},
)
raise SwallableException()
value = [self._jsonify_record(subparser, r, {}) for r in rec[field_name]]
if field.type in ("many2one", "reference"):
value = value[0] if value else None
return value
def _jsonify_record_handle_resolver(self, rec, field, resolver, json_key):
@ -166,7 +174,7 @@ class Base(models.AbstractModel):
value, json_key = value["_value"], value["_json_key"]
return value, json_key
def jsonify(self, parser, one=False):
def jsonify(self, parser, one=False, with_fieldname=False):
"""Convert the record according to the given parser.
Example of (simple) parser:
@ -203,7 +211,12 @@ class Base(models.AbstractModel):
parsers = {False: parser["fields"]} if "fields" in parser else parser["langs"]
for lang in parsers:
translate = lang or parser.get("language_agnostic")
records = self.with_context(lang=lang) if translate else self
new_ctx = {}
if translate:
new_ctx["lang"] = lang
if with_fieldname:
new_ctx["with_fieldname"] = True
records = self.with_context(**new_ctx) if new_ctx else self
for record, json in zip(records, results):
self._jsonify_record(parsers[lang], record, json)

View File

@ -0,0 +1,28 @@
with_fieldname parameter
==========================
The with_fieldname option of jsonify() method, when true, will inject on
the same level of the data "_fieldname_$field" keys that will
contain the field name, in the language of the current user.
Examples of with_fieldname usage:
.. code-block:: python
# example 1
parser = [('name')]
a.jsonify(parser=parser)
[{'name': 'SO3996'}]
>>> a.jsonify(parser=parser, with_fieldname=False)
[{'name': 'SO3996'}]
>>> a.jsonify(parser=parser, with_fieldname=True)
[{'fieldname_name': 'Order Reference', 'name': 'SO3996'}}]
# example 2 - with a subparser-
parser=['name', 'create_date', ('order_line', ['id' , 'product_uom', 'is_expense'])]
>>> a.jsonify(parser=parser, with_fieldname=False)
[{'name': 'SO3996', 'create_date': '2015-06-02T12:18:26.279909+00:00', 'order_line': [{'id': 16649, 'product_uom': 'stuks', 'is_expense': False}, {'id': 16651, 'product_uom': 'stuks', 'is_expense': False}, {'id': 16650, 'product_uom': 'stuks', 'is_expense': False}]}]
>>> a.jsonify(parser=parser, with_fieldname=True)
[{'fieldname_name': 'Order Reference', 'name': 'SO3996', 'fieldname_create_date': 'Creation Date', 'create_date': '2015-06-02T12:18:26.279909+00:00', 'fieldname_order_line': 'Order Lines', 'order_line': [{'fieldname_id': 'ID', 'id': 16649, 'fieldname_product_uom': 'Unit of Measure', 'product_uom': 'stuks', 'fieldname_is_expense': 'Is expense', 'is_expense': False}]}]

View File

@ -121,6 +121,8 @@ class TestParser(TransactionCase):
self.assertEqual(parser, expected_full_parser)
def test_json_export(self):
# will allow to view large dict diff in case of regression
self.maxDiff = None
# Enforces TZ to validate the serialization result of a Datetime
parser = [
"lang",
@ -170,10 +172,61 @@ class TestParser(TransactionCase):
"create_date": "2019-10-31T14:39:49",
"date": "2019-10-31",
}
expected_json_with_fieldname = {
"_fieldname_lang": "Language",
"lang": "en_US",
"_fieldname_comment": "Notes",
"comment": None,
"_fieldname_credit_limit": "Credit Limit",
"credit_limit": 0.0,
"_fieldname_name": "Name",
"name": "Akretion",
"_fieldname_color": "Color Index",
"color": 0,
"_fieldname_children": "Contact",
"children": [
{
"_fieldname_children": "Contact",
"children": [],
"_fieldname_email": "Email",
"email": None,
"_fieldname_country": "Country",
"country": {
"_fieldname_code": "Country Code",
"code": "FR",
"_fieldname_name": "Country Name",
"name": "France",
},
"_fieldname_name": "Name",
"name": "Sebatien Beau",
"_fieldname_id": "ID",
"id": self.partner.child_ids.id,
}
],
"_fieldname_country": "Country",
"country": {
"_fieldname_code": "Country Code",
"code": "FR",
"_fieldname_name": "Country Name",
"name": "France",
},
"_fieldname_active": "Active",
"active": True,
"_fieldname_category_id": "Tags",
"category_id": [{"_fieldname_name": "Tag Name", "name": "Inovator"}],
"_fieldname_create_date": "Created on",
"create_date": "2019-10-31T15:39:49+01:00",
"_fieldname_date": "Date",
"date": "2019-10-31",
}
json_partner = self.partner.jsonify(parser)
self.assertDictEqual(json_partner[0], expected_json)
json_partner_with_fieldname = self.partner.jsonify(
parser=parser, with_fieldname=True
)
self.assertDictEqual(
json_partner_with_fieldname[0], expected_json_with_fieldname
)
# Check that only boolean fields have boolean values into json
# By default if a field is not set into Odoo, the value is always False
# This value is not the expected one into the json