Support deferred attributes in JSONField and improve Django compatibility.

Review Request #10469 — Created March 27, 2019 and submitted — Latest diff uploaded

Information

Djblets
release-2.0.x

Reviewers

JSONField was prone to unwanted queries when working with models
that defferred the JSONField. This wasn't so much a major problem on
Django 1.6, but manifested on newer versions of Django. The core issue
was that, during the model initialization phase, JSONField would try
to load data from the model in order to normalize it, and if the field
was deferred, this act would trigger a query. To fix this, this change
now checks whether the attribute is deferred before performing any
lookups.

Other changes to the parent TextField in newer versions of Django
broke other aspects of JSONField. TextField.get_prep_value() was
added, which forced the value to be a string, and in our case this
resulted in some unwanted serialization. We now override this, instead
of get_db_prep_value() (which will, in the default implementation,
calls our new method and do the right thing).

On the other end of that process is the to_python() method, which we
weren't overriding. We now provide this, and have it return a
deserialized representation of the data.

Djblets and Review Board unit tests pass.

Changes between revision 1 and 2

orig
1
2

Commits

Summary ID Author
Support deferred attributes in JSONField and improve Django compatibility.
JSONField was prone to unwanted queries when working with models that defferred the JSONField. This wasn't so much a major problem on Django 1.6, but manifested on newer versions of Django. The core issue was that, during the model initialization phase, `JSONField` would try to load data from the model in order to normalize it, and if the field was deferred, this act would trigger a query. To fix this, this change now checks whether the attribute is deferred before performing any lookups. Other changes to the parent `TextField` in newer versions of Django broke other aspects of `JSONField`. `TextField.get_prep_value()` was added, which forced the value to be a string, and in our case this resulted in some unwanted serialization. We now override this, instead of `get_db_prep_value()` (which will, in the default implementation, calls our new method and do the right thing). On the other end of that process is the `to_python()` method, which we weren't overriding. We now provide this, and have it return a deserialized representation of the data.
a7dea5c70bc3d5fafc5a579d6d58cc85a8aaa998 Christian Hammond
Support deferred attributes in JSONField and improve Django compatibility.
JSONField was prone to unwanted queries when working with models that defferred the JSONField. This wasn't so much a major problem on Django 1.6, but manifested on newer versions of Django. The core issue was that, during the model initialization phase, `JSONField` would try to load data from the model in order to normalize it, and if the field was deferred, this act would trigger a query. To fix this, this change now checks whether the attribute is deferred before performing any lookups. Other changes to the parent `TextField` in newer versions of Django broke other aspects of `JSONField`. `TextField.get_prep_value()` was added, which forced the value to be a string, and in our case this resulted in some unwanted serialization. We now override this, instead of `get_db_prep_value()` (which will, in the default implementation, calls our new method and do the right thing). On the other end of that process is the `to_python()` method, which we weren't overriding. We now provide this, and have it return a deserialized representation of the data.
676c7f21e9bd03ec3aa66c55654837a0d704714d Christian Hammond
djblets/db/tests/test_json_field.py
Loading...