Allow setting a JSONField to a object or list literal before first save

Review Request #10096 — Created July 19, 2018 and discarded — Latest diff uploaded

Information

Djblets
release-2.0.x

Reviewers

Previously, if one attempted to set a JSONField on an instantiated but
unsaved model instance to an object or list literal
(e.g., mymodel.myfield = {'foo': 'bar'}) the field would attempt to
load the value as if it were a string with json.loads, which would
result in a TypeError.

We are now more deliberate when we call json.loads in post_init --
we only call it for string types. Otherwise, when we receive a value
that could be considered a deserialized JSON value (such as a dict,
list, int, or float), we know that these cannot come from the database
and are therefore being set on an unsaved instance. We then treat them
as deserialized values and do not modify them or attempt to load them.

In the case where we do not understand the type to be a deserialized
value, we still reset the value to an empty object.

Ran unit tests. Without this fix applied, the new unit test fails.