简体   繁体   中英

Outputting a different structure in Django REST Framework

Let's say I have the following model:

class Attribute(models.Model):
    name = models.CharField(max_length=50)
    code = models.CharField(max_length=50)
    value = models.IntegerField(default=0)

How could I get a Django REST Framework serializer to render it as the following?

{
    attribute {
        'name' : 'shoes',
        'code': 'sho',
        'group': {
            'name' : 'shoes',
            'code': 'sho'
         }
    },
    value': 1
}    

Edit: My current serializer, which doesn't get it exactly correct:

from collections import namedtuple

Group = namedtuple('Group', ('name code'))


class GroupSerializer(serializers.Serializer):
    name = serializers.CharField(read_only=True)
    code = serializers.CharField(read_only=True)


class AttributeSerializer(serializers.ModelSerializer):
    name = serializers.CharField()
    code = serializers.CharField()
    value = serializers.IntegerField()
    group = serializers.SerializerMethodField()

    class Meta:
        model = Attribute
        fields = ('name', 'code', 'value', 'group')

    def get_group(self, obj):
        serializer = GroupSerializer(
            Group(name=obj.name, code=obj.code),
        )
        return serializer.data

One solution is View.py

class AttributeView(generics.ListAPIView):
    serializer_class = AttributeSerializer
    queryset = Attribute.objects.all()

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        return Response(dict({"Attribute": serializer.data}))

model.py

class Attribute(models.Model):
    name = models.CharField(max_length=50)
    code = models.CharField(max_length=50)
    value = models.IntegerField(default=0)

    @property
    def get_group(self):
        return dict({"name": self.name, "code": self.code})

serializer.py

class AttributeSerializer(serializers.ModelSerializer):
    group = serializers.ReadOnlyField(source='get_group')
    class Meta:
        model = Attribute
        fields = ('name', 'code', 'value', 'group')

Your best bet would be to override serializer's to_representation .

And return the structure which you want.

Something like this:

class AttributeSerializer(serializers.ModelSerializer):
    name = serializers.CharField()
    code = serializers.CharField()
    value = serializers.IntegerField()
    group = serializers.SerializerMethodField()

    class Meta:
        model = Attribute
       fields = ('name', 'code', 'value', 'group')

    def get_group(self, obj):
        serializer = GroupSerializer(
            Group(name=obj.name, code=obj.code),
        )
        return serializer.data

    def to_representation(self, instance):

        output = super().to_representation(instance)

        value = output.pop('value')

        return {"attribute"  : output, 'value' : value}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM