Как настроить вывод сериализаторов Django Rest Framework?

у меня есть 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
    }
]

как я могу этого достичь ?

2 ответов


создать пользовательский сериализатор поле и реализовать to_native Так, что она возвращает список, который вы хотите.

Если вы используете source="*" техника тогда что-то вроде этого может сработать:

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

надеюсь, это поможет.


ответ Карлтона будет работать отлично. Есть также несколько другие подходы.

вы также можете использовать 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.