Issue with ThumbnailerImageField (ImageField?)
hauru opened this issue · 7 comments
Hi,
I'm using Easy Thumbnails for managing resized versions of images. In my model i have a ThumbnailerImageField which stores a URL to the original image. When trying to serialize an instance of this model, i get the JSON exception:
<ThumbnailerImageFieldFile: ...> is not JSON serializable
ThumbnailerImageField
extends Django's original ImageField
and the Django-provided serialization mechanism works well in this case so i guess it may be a bug.
Hi @hauru. preserialize does not actually encode the data into JSON. It simply creates a data structure based on the arguments in the serialize function. So, if the types in the data structure cannot be encoded by the Django JSON encoder (and therefore the standard library decoder), then the encode may need to be extended to support this type.
Yeah, sorry for that. Thanks for the quick response. Actually i know it isn't supposed to serialize into JSON but it was late yesterday when i was testing it and, as it turns out, my mind was far from being clear.
What i did was to drop-in replace my own serializer, which also converts model instances to regular Python dictionaries. Resulting data is JSON-encoded later with a different function call (using Django's own encoder). I guess what i was expecting from preserialize was the output dictionary values to be plain Python objects. In case of an ImageField
it would mean a regular string with URL. This way doing actual serialization (JSON, XML etc.) wouldn't involve dealing with model fields anymore.
No problem at all.
I guess what i was expecting from preserialize was the output dictionary values to be plain Python objects.
I understand the expectation. However, since arbitrary fields could be defined on a model it would be impossible to account for all cases. That being said, a possible approach would be to coerce objects to a primitive based on it's internal type.
One way of handling this right now, is to use a posthook
which take the model instance and the serialized attributes to perform some processing, such as getting the path string for the image file.
The coercion could use the get_prep_value
method on fields. For example, here is FileField
and it returns a string.
That's what i eventually end up doing. Well, more or less.
In my case the difficulty with posthook
is that it has to be provided separately for the parent model and for each of the "related" fields. It's inconvenient since i need the same common logic to be applied for all model instances (i have ImageField
s in many interrelated models). I ended up modifying your code and adding a separate "global" posthook which gets propagated from the parent serialize
call to subsequent calls for instance's querysets.
Thanks once again!
I have a couple of improvements in the works. #14 defines the Serializer
class to encapsulate these options rather than needing to use globals. I also have a branch to use get_prep_value
as discussed above.
On a side note, some of the CI tests are failing due to Django's AppRegistryNotReady
error. I am less familiar with Django 1.7+ Any thoughts on this? The test script and tests package are pretty basic.
Looks like I figured it out. I was not calling django.setup()
for versions greater than 1.7.