python template Django Rest Framework和JSONField




serializer django rest framework (8)

對於記錄,如果您正在使用PostgreSQL,那麼這“正常工作”,您的模型字段是django.contrib.postgres.JSONField

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

我以前使用過這裡列出的其他幾種解決方案,但是能夠刪除那些額外的代碼。

示例型號:

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']

給定一個帶有JSONField的Django模型,使用Django Rest Framework對它進行序列化和反序列化的正確方法是什麼?

我已經嘗試過to_native一個自定義的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對像中的所有浮點數都成為字符串。


如果你想要jSONField for mysql這是在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()

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

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


DRF為二進制數據提供內置的“JSONField”字段,但只有在設置'binary'標誌為True時才會驗證JSON有效負載然後轉換為utf-8並加載JSON有效負載,否則它只將它們視為字符串(如果無效的json)發送)或json並驗證兩者,即使你創建了JSONField

class JSONSerializer(serializers.ModelSerializer):
    """
    serializer for JSON
    """
    payload = serializers.JSONField(binary=True)

謝謝你的幫助。 這是我最終用於渲染它的代碼

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',)

如果你正在使用mysql(沒有嘗試過其他數據庫),使用DRF的新JSONField和Mark Chackerian建議的JSONSerializerField會將json保存為{u'foo': u'bar'}字符串。 如果你寧願把它保存為{"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)

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

如果您正在使用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()

而且,如果您確實需要序列化二進制數據,您可以隨時復制官方發布代碼





django-rest-framework