I have a table into mysql that is the type TextField (django) by using the JSONField. This is how my model looks
from django.db import models
from json_field import JSONField
class Model(models.Model):
obj = JSONField()
The value I send via tastypie is
json_string = '{"data":"value"}'
Into the database I can see
{"data":"value"}
But when retrive the data with curl I get something like this
"{u'data': u'value'}"
What I can do to not have the python u'field' representation into the tastypie's output ?
thanks!
I fixed this issue like so:
def dehydrate_user_inputs(self, bundle):
requirement = Requirement.objects.get(pk = bundle.obj.pk)
user_inputs = json.dumps(requirement.user_inputs)
return user_inputs
My JSONField is named user_inputs. Requirement is the model that it belongs to.
I feel weird doing a Query here when Tastypie has already done so for me, but, this works. I'd love if there are better solutions.
The error you're seeing is caused by Tastypie treating the JSONField like a TextArea and calling str() on the object JSONField returns before returning it to the caller.
Another approach is to use fields.ApiFields for the JSONField. This works because fields.ApiFields does not perform any conversions on either the way in (hydrate()) or way out (convert()). This is exactly what we want - the underlying JSONField will convert the JSON object to a string for persistence on the way in and recreate the object from the string on the way out. Thus, tastypie does not need to do anything. My code looks a bit like this (class/variable names based on OP's example) -
class JSONField(fields.apiField):
""" Wrapper over fields.apiField to make what we're doing here clear """
pass
class MyModelResource(ModelResource):
obj = JSONField('obj')
Use DictField
:
obj = fields.DictField(attribute='obj')
I was running into similar problems where my unicode strings would be returned in a weird format in the API (I think the raw encoded strings were returned as opposed to the actual utf-8 characters).
Anyway instead of using the dehydrate method and re-doing the query, you are better off with a custom serializer in your resources.
This is what I used:
class JSONSerializer(Serializer):
'''using the standard json library for better unicode support,
also note django.utils.simplejson, used in the standard Tastypie serializer,
is set for depreciation'''
def to_json(self, data, options=None):
options = options or {}
data = self.to_simple(data, options)
return json.dumps(data)
then in your resources:
class PlaceResource(ModelResource):
class Meta:
queryset = Place.objects.all()
resource_name = 'place'
serializer = JSONSerializer()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With