Django Rest Framework and JSONField

2019-01-08 16:34发布

Given a Django model with a JSONField, what is the correct way of serializing and deserializing it using Django Rest Framework?

I've already tried crating a custom serializers.WritableField and overriding to_native and from_native:

from json_field.fields import JSONEncoder, JSONDecoder
from rest_framework import serializers

class JSONFieldSerializer(serializers.WritableField):
    def to_native(self, obj):
    return json.dumps(obj, cls = JSONEncoder)

    def from_native(self, data):
        return json.loads(data, cls = JSONDecoder)

But when I try to updating the model using partial=True, all the floats in the JSONField objects become strings.

10条回答
一夜七次
2楼-- · 2019-01-08 17:04

If you want JSONField for mysql this is done in django-mysql and serializer was fixed some day ago [1], is not yet in any release.

[1] https://github.com/adamchainz/django-mysql/issues/353

setting.py

add:

    'django_mysql',

models.py

from django_mysql.models import JSONField

class Something(models.Model):
(...)
    parameters = JSONField()
查看更多
▲ chillily
3楼-- · 2019-01-08 17:08

Thanks by the help. This is the code i finally use for render it

class JSONSerializerField(serializers.Field):
    """Serializer for JSONField -- required to make field writable"""

    def to_representation(self, value):
        json_data = {}
        try:
            json_data = json.loads(value)
        except ValueError as e:
            raise e
        finally:
            return json_data

    def to_internal_value(self, data):
        return json.dumps(data)

class AnyModelSerializer(serializers.ModelSerializer):
    field = JSONSerializerField()

    class Meta:
        model = SomeModel
        fields = ('field',)
查看更多
霸刀☆藐视天下
4楼-- · 2019-01-08 17:12

serializers.WritableField is deprecated. This works:

from rest_framework import serializers
from website.models import Picture


class PictureSerializer(serializers.HyperlinkedModelSerializer):
    json = serializers.SerializerMethodField('clean_json')

    class Meta:
        model = Picture
        fields = ('id', 'json')

    def clean_json(self, obj):
        return obj.json
查看更多
三岁会撩人
5楼-- · 2019-01-08 17:14

In 2.4.x:

from rest_framework import serializers # get from https://gist.github.com/rouge8/5445149

class WritableJSONField(serializers.WritableField):
    def to_native(self, obj):
        return obj


class MyModelSerializer(serializers.HyperlinkedModelSerializer):
    my_json_field = WritableJSONField() # you need this.
查看更多
登录 后发表回答