2013-08-02 9 views
7

Mam modelu Django, który jest tak:W jaki sposób można dostosować dane wyjściowe serializatorów Django Rest Framework?

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

i dwa serializers, zdefiniowana jako:

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

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

Gdy dostęp do serializatora nad zdaniem, pojawia się następujący komunikat:

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

Prawie dobrze, z wyjątkiem tego, że wolałbym mieć:

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

Jak mogę to osiągnąć?

Odpowiedz

11

Utwórz custom serializer field i zaimplementuj to_native, aby zwrócić wybraną listę.

Jeśli używasz source="*" technique wtedy coś takiego może działać:

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

Mam nadzieję, że pomaga.

+0

Wszystkie podane linki są zepsute. Czy mógłbyś je zaktualizować? – vimal1083

+0

Proszę. –

6

Odpowiedź Carltona będzie działać dobrze. Jest też kilka innych podejść, które możesz podjąć.

Można również użyć SlugRelatedField, który reprezentuje relację, używając danego pola na celu.

Tak na przykład ...

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

Alternatywnie, jeżeli __str__ z WindowsMacAddress prostu wyświetla adres, a następnie można po prostu użyć RelatedField, który jest podstawowym tylko do odczytu pole, które daje prosta ciągła reprezentacja celu relacji.

# 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() 

Spójrz przez documentation on serializer fields aby uzyskać lepszy pomysł na różne sposoby można reprezentują relacje w swoim API.

+0

Hmm Myślałem, że 'RelatedField' i' SlugRelatedField' działają tylko z 'ModelSerializer'? –

+0

Wszystkie pola relacyjne działają z relacjami modelu Django. Działają dobrze, albo są używane w klasie 'Serializer' lub' ModelSerializer'. –

+0

Dzięki! Przyda mi się to później. –

Powiązane problemy