This question has been flagged
2 Replies
20916 Views

Hi, I have a model with a json field. I am trying to create a view for that model.
Approach 1: I want to parse the json field and then show that in UI. but I did not know how to achieve that.

Approach 2: Then I started with simply showing the json on UI. but it straight away gave an error.

my view is

<record id="view_farmpoint_tree" model="ir.ui.view">
<field name="name">fnf_geo.farmpoint.tree</field>
<field name="model">farmpoint</field>
<field name="arch" type="xml">
<tree string="Farm points">
<field name="coordinates"/>
<field name="is_success"/>
<field name="partner_id"/>
</tree>
</field>
</record>


my model is

class FarmPoint(models.Model):
_name = "farmpoint"
_description = "Stores coordinates of farms"

coordinates = fnf_fields.JSONB(string="Coordinates", required=True)
is_success = fields.Boolean(string="Successful data collection",
required=True, default=True)
partner_id = fields.Many2one('res.partner', string='Partner ID',
required=True, ondelete='restrict')


I was able to figure out that odoo does not support json as field, we have added custom field in odoo, and that's why it is not working.

I want to make it work as Approach 1, but any help is appreciated.


Avatar
Discard
Best Answer

Hi Pawan,

Why don't you just go with a plain text field (fields.Text) in which you store the JSON preformatted?
I assume that you get the JSON data from an API call so you can then format it with some Python code:

json.dumps(your_json_string, indent=4, sort_keys=True)

This will format and indent the JSON which you can then simply show in the views.

Regards,
Yenthe

Avatar
Discard
Author

Thanks for the answer @yenthe, that is how I solved it later.

This can work but is there a way to make use of the Postgres JSON field type which is very powerful in queries on JSON attributes and fields (not like a simple text column) ?

@Razvan it is possible but then you'd need to introduce a new field type into the core of Odoo as Odoo native doesn't support it.

Best Answer

I also needed a json computed field on one of the models (a dict with some strings).







Creating a custom field type that can map to the json type in PostgreSQL is just the first step.



from odoo.fields import Field

import psycopg2



class JsonField(Field):

"""

Represents a postgresql Json column (JSON values are mapped to the Python equivalent type of list/dict).

"""

type = 'json' # Odoo type of the field (string)

column_type = ('json', 'json') # database column type (ident, spec)



def convert_to_column(self, value, record, values=None, validate=True):

""" Convert ``value`` from the ``write`` format to the SQL format. """

# By default the psycopg2 driver does not know how to map dict/list to postgresql json types

# We need to convert it to the right db type when inserting in the db

if value is None:

return None

else:

return \psycopg2\.extras\.Json\(value\)\\
\
\
\
\
\
\
\
Using\ it\ in\ the\ model\ is\ also\ easy\:\
\
\
\
from\ odoo\ import\ models\,\ fields\,\ api\
\
from\ json_field\ import\ JsonField\
\
\
\
class\ Person\(models\.Model\)\:\
\
\ \ \ \ _name\ \=\ \'example\.person\'\
\
\ \ \ \ _description\ \=\ \'Person\ with\ json\ details\'\
\
\ \ \ \ \
\
\ \ \ \ details\ \=\ JsonField\(\)\ \#\ a\ json\ object\ represented\ as\ dict\ \/\ list\ \/\ python\ primitives\
\
\
\
The\ hard\ part\ was\ getting\ the\ ui\ to\ recognize\ the\ field\ type\ to\ show\ and\ edit\ it\.\
\
\
\
I\ added\ all\ \ the\ code\ in\ this\ \ gist\ \ because\ \ it\'s\ \ a\ \ bit\ \ too\ \ long\ to\ write\ \ here\ \:\ \ \https://gist.github.com/danmana/5242f37b7d63daf4698de7c61c8b59fc#file-json_field-js



Note: There might be things I missed, I only needed it in a custom Kanban card (but the list view and edit seem to work fine).

It works ok as a computed field as well (or a normal field stored in db)




Avatar
Discard

Thank you very much for sharing this code! Would you like to publish it as an Odoo module in one of the repositories of https://github.com/oca ?

Hi Henrik,
I'm glad this helped (sorry for the bad formatting, I haven't figured out yet how to paste code on this forum).
Unfortunately at the moment I don't have any time to make a PR and properly test this code.
Feel free to copy the code and make a PR yourself :)