Django Rest框架和JSONField

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

我已经试过创build一个自定义的serializers.WritableField并覆盖to_nativefrom_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对象中的所有浮点数都变成了string。

如果您使用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 

然后在模型中join像这样的字段

 class MySerializer(serializers.ModelSerializer): json_data = JSONSerializerField() 

而且,如果您确实需要序列化二进制数据,则可以随时复制正式版本代码

在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. 

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 

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

例如:

 class MyModelSerializer(serializers.HyperlinkedModelSerializer): my_json_field = serializers.DictField() 

它工作正常,与GET/PUT/PATCH/POST ,包括嵌套的内容。

马克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 

工作正常。 在Django 1.8中使用DRF 3.15和JSONFields

为了logging,如果您正在使用PostgreSQL,则此“正常工作”,并且您的模型字段是django.contrib.postgres.JSONField

我在PostgreSQL 9.4,Django 1.9和Django REST Framework 3.3.2。

我以前使用过这里列出的其他解决scheme,但能够删除额外的代码。

示例模型:

 class Account(models.Model): id = UUIDField(primary_key=True, default=uuid_nodash) data = JSONField(blank=True, default="") 

示例串行器:

 class AccountSerializer(BaseSerializer): id = serializers.CharField() class Meta: model = Account fields = ('id','data') 

示例视图:

 class AccountViewSet( viewsets.GenericViewSet, mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin ): model = Account queryset = Account.objects.all() serializer_class = AccountSerializer filter_fields = ['id', 'data'] 

如果你正在使用mysql(还没有尝试过使用其他数据库),使用DRF的新JSONField和Mark Chackerianbuild议的JSONSerializerField将把json保存为{u'foo': u'bar'}string。 如果你把它保存为{"foo": "bar"} ,这对我有用:

 import json class JSONField(serializers.Field): def to_representation(self, obj): return json.loads(obj) def to_internal_value(self, data): return json.dumps(data) 

如果你想为MySQL的JSONField,这是在Django的MySQL和序列化器已经修复了一天前[1],尚未在任何版本。

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

setting.py

加:

  'django_mysql', 

models.py

 from django_mysql.models import JSONField class Something(models.Model): (...) parameters = JSONField()