[Django]-Trying to understand JSONField for django postgresql

4👍

For Django database fields, there are three relevant states/representations of the same data: form, python and database. In case of the example HandField, form/database representations are the same string, the python representation is the Hand object instance.

In case of a custom field on top of JSONField, the internal python might be a LiftSerie instance, the form representation a json string, the value sent to the database a json string and the value received from the database a json structure converted by psycopg2 from the string returned by postgres, if that makes sense.

In terms of your questions:

  1. The python value is not customized, so the python data type of the field is the same as the expected input. In contrast to the HandField example, where the input could by a string or a Hand instance. In the latter case, the base Field.to_python() implementation, which just returns the input would be enough.

  2. Psycopg2 already converts the database value to json, see 5. This is also true for other types like int/IntegerField.

  3. from_db_value is not defined in the base Field class, but it is certainly taken into account if it exists. If you look at the implementation of Field.get_db_converters(), from_db_value is added to it if the Field has an attribute named like that.

  4. The django.contrib.postgres.JSONField has an optional encoder argument. By default, it uses json.dumps without an encoder to convert a json structure to JSON string.

  5. psycopg2 automatically convertes from database types to python types. It’s called adaptation. Documentation for JSON adaptation explains how that works and can be customized.

Note that when implementing a custom field, I would suggest writing tests for it during development, especially if the mechanisms are not completely understood. You can get inspiration for such tests in for example django-localflavor.

👤Jieter

0👍

Short answer is, both to_python and from_db_value return python strings that should serialize to JSON with no encoding errors, all things being equal.

If you’re okay with strings, that’s fine but I usually override Django’s JSONFields’s from_db_value method to return a dict or a list, not a string for use in my code. I created a custom field for that.

To me, the whole point of a Json field is to be able to interact with it’s values as dicts or lists.

Leave a comment