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:
-
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 aHand
instance. In the latter case, the baseField.to_python()
implementation, which just returns the input would be enough. -
Psycopg2 already converts the database value to json, see 5. This is also true for other types like int/
IntegerField
. -
from_db_value
is not defined in the baseField
class, but it is certainly taken into account if it exists. If you look at the implementation ofField.get_db_converters()
,from_db_value
is added to it if theField
has an attribute named like that. -
The
django.contrib.postgres.JSONField
has an optional encoder argument. By default, it usesjson.dumps
without an encoder to convert a json structure to JSON string. -
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.
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.