9

我有一个这样的 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
    }
]

我怎样才能做到这一点?

4

2 回答 2

15

创建一个自定义序列化器字段并实现to_native,以便它返回您想要的列表。

如果您使用该source="*"技术,那么这样的事情可能会起作用:

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

我希望这会有所帮助。

更新djangorestframework>=3.9.1

根据文档to_representation(),现在您需要覆盖andto_internal_value()方法中的一个或两个。例子

class CustomField(Field):
    def to_representation(self, value)
        return {'id': value.id, 'name': value.name}
于 2013-08-02T09:33:12.403 回答
7

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

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

所以例如...

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

或者,如果 的__str__简单WindowsMacAddress地显示地址,那么您可以简单地使用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()

查看有关序列化器字段的文档,以更好地了解可以在 API 中表示关系的各种方式。

于 2013-08-02T09:46:59.407 回答