My team develops a rather complex Django service, that uses
django-jsonfield in multiple places for some while.
Recently we added a new feature - sending invitation emails.
It was rather simple task, because we took magnificient
Everything went fine, until we realized that unit tests for models,
that has JSONFields started to fail with cryptic errors.
Turned out, that
django-post-office depends on
And this package is slightly different from the one we already use.
They conflict, because both packages install into
They have exactly the same public interface and are interchangeble in most cases.
pip does nothing to handle or detect this conflict and mixes both
packages into single directory producing unpredictable Frankenshtein.
I dug a little summary on them:
Maintainer: Dan Koch Source: https://github.com/dmkoch/django-jsonfield Current Version: 2.0.2 PyPI: https://pypi.python.org/pypi/jsonfield
Maintainer: Matthew Schinckel Source: https://bitbucket.org/schinckel/django-jsonfield Current version: 1.0.1 PyPI: https://pypi.python.org/pypi/django-jsonfield
Post office uses the first one, by Dan Koch. It perfectly fulfills their needs.
But it doesn’t work correctly with
django.utils.model_to_dict - it
returns dumped JSON string representation, instead of object.
Here is the code responsible for this [mis]behavior:
def value_from_object(self, obj, dump=True):
value = super(JSONFieldBase, self).value_from_object(obj)
if self.null and value is None:
return self.dumps_for_display(value) if dump else value
It dumps value by default, while model_to_dict expects it to return value unchanged.
JSONField by Matthew Schinckel doesn’t override
and works as Django expects.
Once we discovered the full story we had three options:
django-post-officeto another library that doesn’t have dependency conflicts.
Extract email sending to separate service and remove dependency conflict.
Inherit Koch’s jsonfield and override problematic method.
I went with option 3.
At the same time I opened a PR to
to switch to the one and true