Django (JSONField) and tastypie

半世苍凉 提交于 2019-12-01 16:41:13

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()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!