如何自定义 Django Rest Framework 序列化程序输出?

Posted

技术标签:

【中文标题】如何自定义 Django Rest Framework 序列化程序输出?【英文标题】:How can one customize Django Rest Framework serializers output? 【发布时间】: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
    
]

我怎样才能做到这一点?

【问题讨论】:

【参考方案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 类上使用它们都可以正常工作。 谢谢!以后对我有用。

以上是关于如何自定义 Django Rest Framework 序列化程序输出?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django rest 框架中添加自定义权限和角色

如何在 Django REST 框架中为多对多字段定义“IsOwner”自定义权限?

如何自定义 Django Rest Framework 序列化程序输出?

如何在 django rest 框架中反转 ViewSet 自定义操作的 URL

Django Rest Framework 自定义身份验证

如何自定义 Django REST Framework GET 请求的响应?