Django Rest Framework和JSONField

Tza*_*ach 51 python django django-models django-rest-framework

给定一个带有JSONField的Django模型,使用Django Rest Framework对它进行序列化和反序列化的正确方法是什么?

我已经尝试过装箱定制serializers.WritableField和覆盖,to_native并且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)
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用更新模型时partial=True,JSONField对象中的所有浮动都变为字符串.

Mar*_*ian 64

如果您正在使用Django Rest Framework> = 3.3,那么现在包含 JSONField序列化程序.现在这是正确的方法.

如果您使用的是Django Rest Framework <3.0,那么请参阅gzerone的回答.

如果您使用的是DRF 3.0 - 3.2并且无法升级,则无需序列化二进制数据,请按照这些说明进行操作.

首先声明一个字段类:

from rest_framework import serializers

class JSONSerializerField(serializers.Field):
    """ Serializer for JSONField -- required to make field writable"""
    def to_internal_value(self, data):
        return data
    def to_representation(self, value):
        return value
Run Code Online (Sandbox Code Playgroud)

然后将字段添加到模型中

class MySerializer(serializers.ModelSerializer):
    json_data = JSONSerializerField()
Run Code Online (Sandbox Code Playgroud)

而且,如果您确实需要序列化二进制数据,您可以随时复制官方发布代码

  • 应该使用GET/POST/PATCH/POST (2认同)

gze*_*one 18

在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.
Run Code Online (Sandbox Code Playgroud)

  • 这仅适用于Django Rest Framework版本2.对于版本3,请参阅Mark Chackerian的回答. (6认同)
  • 我建议不要使用JSONField作为类名,因为它会与其他类冲突. (3认同)

Joc*_*nde 6

当且仅当您知道 JSON 内容的第一级样式(List 或 Dict)时,您可以使用 DRF 内置DictFieldListField

前任:

class MyModelSerializer(serializers.HyperlinkedModelSerializer):
    my_json_field = serializers.DictField()
Run Code Online (Sandbox Code Playgroud)

它工作得很好,包括GET/PUT/PATCH/POST嵌套内容。


Dav*_*han 5

不推荐使用serializers.WritableField.这有效:

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
Run Code Online (Sandbox Code Playgroud)