【问题标题】:How can one customize Django Rest Framework serializers output?如何自定义 Django Rest Framework 序列化程序输出?
【发布时间】:2013-08-03 11:23:19
【问题描述】:

我有一个这样的 Django 模型:

class WindowsMacAddress(models.Model):
    address = models.TextField(unique=True)
    mapping = models.ForeignKey('imaging.WindowsMapping', related_name='macAddresses')

还有两个序列化器,定义为:

class WindowsFlatMacAddressSerializer(serializers.Serializer):
    address = serializers.Field()

class WindowsCompleteMappingSerializer(serializers.Serializer):
    id = serializers.Field()
    macAddresses = WindowsFlatMacAddressSerializer(many=True)
    clientId = serializers.Field()

通过视图访问序列化程序时,我得到以下输出:

[
    {
        "id": 1, 
        "macAddresses": [
            {
                "address": "aa:aa:aa:aa:aa:aa"
            }, 
            {
                "address": "bb:bb:bb:bb:bb:bb"
            }
        ], 
        "clientId": null
    }
]

几乎不错,只是我更喜欢:

[
    {
        "id": 1, 
        "macAddresses": [
            "aa:aa:aa:aa:aa:aa",
            "bb:bb:bb:bb:bb:bb"
        ],
        "clientId": null
    }
]

我怎样才能做到这一点?

【问题讨论】:

    标签: python django json django-rest-framework


    【解决方案1】:

    创建一个custom serializer field 并实现to_native 以便它返回您想要的列表。

    如果你使用source="*" technique,那么这样的东西可能会起作用:

    class CustomField(Field):
        def to_native(self, obj):
            return obj.macAddresses.all()
    

    希望对你有帮助。

    更新 djangorestframework>=3.9.1

    根据documentation,现在您需要覆盖to_representation()to_internal_value() 方法之一或两者。示例

    class CustomField(Field):
        def to_representation(self, value)
            return {'id': value.id, 'name': value.name}
    

    【讨论】:

    • 所有链接都失效了,请更新一下
    【解决方案2】:

    卡尔顿的回答可以很好地完成这项工作。您还可以采取其他几种方法。

    您还可以使用SlugRelatedField,它表示关系,使用目标上的给定字段。

    比如说……

    class WindowsCompleteMappingSerializer(serializers.Serializer):
        id = serializers.Field()
        macAddresses = serializers.SlugRelatedField(slug_field='address', many=True, read_only=True)
        clientId = serializers.Field()
    

    或者,如果WindowsMacAddress__str__ 只显示地址,那么您可以简单地使用RelatedField,这是一个基本的只读字段,将为您提供关系目标的简单字符串表示。

    # models.py
    class WindowsMacAddress(models.Model):
        address = models.TextField(unique=True)
        mapping = models.ForeignKey('imaging.WindowsMapping', related_name='macAddresses')
    
        def __str__(self):
            return self.address
    
    # serializers.py
    class WindowsCompleteMappingSerializer(serializers.Serializer):
        id = serializers.Field()
        macAddresses = serializers.RelatedField(many=True)
        clientId = serializers.Field()
    

    查看documentation on serializer fields,以更好地了解在 API 中表示关系的各种方式。

    【讨论】:

    • 嗯,我以为 RelatedFieldSlugRelatedField 只适用于 ModelSerializer
    • 所有关系字段都适用于 Django 模型关系。在 SerializerModelSerializer 类上使用它们都可以正常工作。
    • 谢谢!以后对我有用。
    猜你喜欢
    • 2016-11-28
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 2020-08-04
    相关资源
    最近更新 更多