简体   繁体   中英

How to get attribute of related object set in DRF serializer?

I am trying to nest data from a single attribute of a related set in one of my DRF serializers.

So far, I am only able to do it through an intermediary serializer, which seems messy. I would like to do it directly.

As of now, this is the structure of my result:

[
    {
        "id": 1,
        "name": "Pinot Noir",
        "wine_list": [
            {
                "id": 1,
                "wine": {
                    "id": 1,
                    "name": "Juan Gil"

                }
            }
        ]
    }
]

The extra "wine_list" is redundant and surely unnecessary. I have achieved this with the following code.

These are my models. I have simplified them to include the necessary information only.

class Varietal(models.Model):
    name = models.CharField(max_length=50)


class Wine(models.Model):
    name = models.CharField(max_length=100)


class WineVarietal(models.Model):
    wine = models.ForeignKey(Wine, on_delete=models.CASCADE)
    varietal = models.ForeignKey(Varietal, on_delete=models.CASCADE)

These are the serializers I am working with now.

class VarietalDetailWineSerializer(ModelSerializer):
    class Meta:
        model = Wine
        fields = ['id', 'name']


class VarietalDetailWineVarietalSerializer(ModelSerializer):
    wine = VarietalDetailWineSerializer()

    class Meta:
        model = WineVarietal
        fields = ['id', 'wine']


class VarietalDetailSerializer(ModelSerializer):
    wine_list = VarietalDetailWineVarietalSerializer(source='winevarietal_set', many=True)

    class Meta:
        model = Varietal
        fields = ['id', 'name', 'wine_list']

Ideally, I would get something like this:

[
    {
        "id": 1,
        "name": "Pinot Noir",
        "wine": [
            {
                "id": 1,
                "name": "Juan Gil"

            }
        ]
    }
]

With code somewhat like this:

class VarietalDetailWineSerializer(ModelSerializer):
    class Meta:
        model = Wine
        fields = [
            'id',
            'name',
        ]


class VarietalDetailSerializer(ModelSerializer):
    wine = VarietalDetailWineSerializer(source='winevarietal_set.wine', many=True)

    class Meta:
        model = Varietal
        fields = [
            'id',
            'name',
            'wine',
        ]

But that source value is invalid.

Peace.

One possible way to achieve this is to use serializerMethodField .

class VarietalDetailSerializer(ModelSerializer):
    wine = SerializerMethodField()

    class Meta:
        model = Varietal
        fields = [
            'id',
            'name',
            'image',
            'description',
            'wine',
            'active'
        ]

    def get_wine(self, varietal):
        wine_varietals = varietal.winevarietal_set.all()

        wine = [wine_varietals.wine for wine_varietals in wine_varietals]

        return VarietalDetailWineSerializer(instance=wine, many=True).data

Our main target is to add many-to-many fields response from a custom serializer method.

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