Fong Tom
Fong Tom

Reputation: 87

django REST framework remove nested json

I would like to get the data from multiple model, now I work as these:

class IGStatSerializer(serializers.ModelSerializer):
    class Meta:
        model = IGStat
        fields = [
            "account",
            "rank",
            "followers",
            "created",
        ]


class IGSerializer(serializers.ModelSerializer):
    stats = serializers.SerializerMethodField()

    class Meta:
        model = IGAccount
        fields = [
            "id",
            "username",
            "avatar",
            "brand",
            "stats",]
    def get_stats(self, instance):
        today = datetime.today() - timedelta(days=1)
        stat = instance.stats.all().filter(created__year=today.year,
                                           created__month=today.month,
                                           created__day=today.day)
        return IGStatSerializer(stat, allow_null=True, many=True).data

And the json result will be like this:

{
                "id": 3613,
                "username": "beautyfromnaturehk",
                "avatar": "https://scontent-iad3-1.cdninstagram.com/v/t51.2885-19/s320x320/42763479_187833352109784_1648992215864705024_n.jpg?tp=1&_nc_ht=scontent-iad3-1.cdninstagram.com&_nc_ohc=Q4hJvaXL-vYAX--Ol1x&oh=e05aef733557c9951642c3c8b518d2f9&oe=607A54CC",
                "brand": 4172,
                "stats": [
                    {
                        "account": 3613,
                        "rank": 22822,
                        "followers": 21485,
                        "created": "2021-03-16T00:00:00Z"
                    }
                ]
            },

And in actual case, there will combine more than one models together and having many nested json. So I would like to remove the nested and rename the field name, like the above case should be like this:

{
            "id": 3613,
            "username": "beautyfromnaturehk",
            "avatar": "https://scontent-iad3-1.cdninstagram.com/v/t51.2885-19/s320x320/42763479_187833352109784_1648992215864705024_n.jpg?tp=1&_nc_ht=scontent-iad3-1.cdninstagram.com&_nc_ohc=Q4hJvaXL-vYAX--Ol1x&oh=e05aef733557c9951642c3c8b518d2f9&oe=607A54CC",
            "brand": 4172,
            "stats_account": 3613,
            "stats_rank": 22822,
            "stats_followers": 21485,
            "stats_created": "2021-03-16T00:00:00Z"
        },

The stats nested was remove and rename the content of it.

Upvotes: 1

Views: 961

Answers (1)

Muhammad Hassan
Muhammad Hassan

Reputation: 14391

Write custom to_representation function in your serializer like this

class IGStatSerializer(serializers.ModelSerializer):
    class Meta:
        model = IGStat
        fields = [
            "account",
            "rank",
            "followers",
            "created",
        ]


class IGSerializer(serializers.ModelSerializer):
    stats = serializers.SerializerMethodField()

    class Meta:
        model = IGAccount
        fields = [
            "id",
            "username",
            "avatar",
            "brand",
            "stats",]
    def get_stats(self, instance):
        today = datetime.today() - timedelta(days=1)
        stat = instance.stats.all().filter(created__year=today.year,
                                           created__month=today.month,
                                           created__day=today.day)
        return IGStatSerializer(stat, allow_null=True, many=True).data

    def to_representation(self, instance):
        data = super().to_representation(instance)
        stats = data.pop('stats', None)
        # If you are sure that there will be only one stats object
        for key, value in stats[0].items():
            data['stats_{key}'.format(key=key)] = value
        return data
    

Upvotes: 1

Related Questions