[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 fixpull/3205/head
parent
908a4c5956
commit
aee47a5e41
|
@ -103,6 +103,13 @@ class Base(models.AbstractModel):
|
||||||
value, json_key = self._jsonify_record_handle_resolver(
|
value, json_key = self._jsonify_record_handle_resolver(
|
||||||
rec, field, resolver, json_key
|
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)
|
self._add_json_key(root, json_key, value)
|
||||||
return root
|
return root
|
||||||
|
|
||||||
|
@ -150,10 +157,11 @@ class Base(models.AbstractModel):
|
||||||
{"model": self._name, "fname": field_name},
|
{"model": self._name, "fname": field_name},
|
||||||
)
|
)
|
||||||
raise SwallableException()
|
raise SwallableException()
|
||||||
|
|
||||||
value = [self._jsonify_record(subparser, r, {}) for r in rec[field_name]]
|
value = [self._jsonify_record(subparser, r, {}) for r in rec[field_name]]
|
||||||
|
|
||||||
if field.type in ("many2one", "reference"):
|
if field.type in ("many2one", "reference"):
|
||||||
value = value[0] if value else None
|
value = value[0] if value else None
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _jsonify_record_handle_resolver(self, rec, field, resolver, json_key):
|
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"]
|
value, json_key = value["_value"], value["_json_key"]
|
||||||
return 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.
|
"""Convert the record according to the given parser.
|
||||||
|
|
||||||
Example of (simple) parser:
|
Example of (simple) parser:
|
||||||
|
@ -203,7 +211,12 @@ class Base(models.AbstractModel):
|
||||||
parsers = {False: parser["fields"]} if "fields" in parser else parser["langs"]
|
parsers = {False: parser["fields"]} if "fields" in parser else parser["langs"]
|
||||||
for lang in parsers:
|
for lang in parsers:
|
||||||
translate = lang or parser.get("language_agnostic")
|
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):
|
for record, json in zip(records, results):
|
||||||
self._jsonify_record(parsers[lang], record, json)
|
self._jsonify_record(parsers[lang], record, json)
|
||||||
|
|
||||||
|
|
|
@ -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}]}]
|
|
@ -121,6 +121,8 @@ class TestParser(TransactionCase):
|
||||||
self.assertEqual(parser, expected_full_parser)
|
self.assertEqual(parser, expected_full_parser)
|
||||||
|
|
||||||
def test_json_export(self):
|
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
|
# Enforces TZ to validate the serialization result of a Datetime
|
||||||
parser = [
|
parser = [
|
||||||
"lang",
|
"lang",
|
||||||
|
@ -170,10 +172,61 @@ class TestParser(TransactionCase):
|
||||||
"create_date": "2019-10-31T14:39:49",
|
"create_date": "2019-10-31T14:39:49",
|
||||||
"date": "2019-10-31",
|
"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)
|
json_partner = self.partner.jsonify(parser)
|
||||||
|
|
||||||
self.assertDictEqual(json_partner[0], expected_json)
|
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
|
# 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
|
# 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
|
# This value is not the expected one into the json
|
||||||
|
|
Loading…
Reference in New Issue