【问题标题】:Serializing a list of object as dictionnary in DjangoRestFramework在 Django Rest Framework 中将对象列表序列化为字典
【发布时间】:2013-05-23 13:44:54
【问题描述】:

使用 django 和 django-rest-framework,我有以下模型(这是简化的,但都在那里):

class Device(Model):
    #stuff

class DeviceInformation(Model):
    device = ForeignKey(Device, reverse='infos')
    key = CharField(max_length=32)
    value = CharField(max_length=1024)

当通过 django-rest-framework 的 ModelSerializer 序列化设备时,我得到如下信息:

{
    //stuff
    infos: [{
        'key':'BatteryLevel',
        'value':'80%'
    },{
        'key':'DeviceName',
        'value':'my device'
    }, //etc
    ]
}

这是完全正常的。然而,序列化成这样的东西会更有意义:

{
    //stuff
    infos: {
        'BatteryLevel':'80%',
        'DeviceName':'my device',
        //etc
    }
}

我该怎么做?甚至可能吗? 请注意,我不需要反序列化任何这些信息。

编辑:我的序列化程序如下:

class DeviceInfoSerializer(ModelSerializer):
    class Meta:
        model = DeviceInformation
        fields = ('key', 'value')
        read_only_fields = fields


class DeviceSerializer(HyperlinkedModelSerializer):

    udid = serializers.CharField(read_only=True)

    def __init__(self, *args, **kwargs):
        super(DeviceSerializer, self).__init__(*args, **kwargs)
        if hasattr(self, 'object') and self.object and not self.many:
            self.data['infos'] = DeviceInfoSerializer(
                self.object.infos.all(), many=True).data

    class Meta:
        model = Device
        fields = ['udid', 'model', 'tracked']
        read_only_fields = ('model', 'tracked')
        slug_field = 'udid'

【问题讨论】:

  • 不是专家,如果您覆盖 get_field(..)get_key_field()get_value_field() 会怎样。看这里django-rest-framework.org/api-guide/…
  • 检查源代码后,这将不起作用。但是,通过编写自定义 Field 并覆盖 to_native(...) 应该可以实现这一点。不过,我觉得这很像 hack。
  • 你的序列化器是什么样的?

标签: django json serialization django-rest-framework


【解决方案1】:

对于您的只读情况,最好的方法是使用SerializerMethodField

这将更改您的DeviceSerializer 并消除对您的DeviceInfoSerializer 的需求。

class DeviceSerializer(HyperlinkedModelSerializer):
    udid = serializers.CharField(read_only=True)
    infos = serializers.SerializerMethodField('get_infos')

    def get_infos(self, obj):
        return {
            info.key: info.value
            for info in obj.infos.all()
        }

    class Meta:
        model = Device
        fields = ['udid', 'model', 'tracked', 'infos']
        read_only_fields = ('model', 'tracked', 'infos')
        slug_field = 'udid'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 2017-07-12
    • 2014-02-09
    • 1970-01-01
    • 2016-10-22
    • 2020-10-30
    • 2019-03-16
    相关资源
    最近更新 更多