Django Rest Framework与JSONField
在Django模型中,如果有一个JSONField,那么使用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)
但是当我尝试使用partial=True
来更新模型时,JSONField里面的所有浮点数都变成了字符串。
11 个回答
4
Mark Chackerian 的脚本对我来说没用,我不得不强制进行 JSON 转换:
import json
class JSONSerializerField(serializers.Field):
""" Serializer for JSONField -- required to make field writable"""
def to_internal_value(self, data):
json_data = {}
try:
json_data = json.loads(data)
except ValueError, e:
pass
finally:
return json_data
def to_representation(self, value):
return value
这样做没问题。我使用的是 DRF 3.15 和 Django 1.8 中的 JSONFields。
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
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.
82
如果你使用的是 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
然后把这个字段添加到模型中,像这样:
class MySerializer(serializers.ModelSerializer):
json_data = JSONSerializerField()
如果你确实需要序列化二进制数据,你可以随时复制 官方发布的代码。