Fong Tom
Fong Tom

Reputation: 87

save to model after computed in serializer

The serializer will computed the average score of the data and return to view in field weekly_score

class BrandChartsSerializer(serializers.ModelSerializer):
    rankings = serializers.SerializerMethodField()
    instagram = IGSerializer(allow_null=True)
    facebook = FBSerializer(allow_null=True)
    hashtags = BrandHashtagSerializer(allow_null=True, many=True)
    # rename the json field
    brand_uid = serializers.IntegerField(source='id')
    brand_name = serializers.CharField(source='name')
    origin = serializers.CharField(source="country")
    weekly_score = serializers.SerializerMethodField()

    class Meta:
        model = Brand
        fields = [
            "rankings",
            "brand_uid",
            "brand_name",
            "origin",
            "instagram",
            "facebook",
            "hashtags",
            "weekly_score",
        ]


    def get_weekly_score(self,instance):
        data = self.get_rankings(instance)
        result = 0
        counter = 0
        while data:
            rankings = data.pop()
            for key,value in rankings.items():
                isFloat = isinstance(value,float)
                if isFloat:
                    result += value
                    counter += 1
        if counter is not 0:
            result = result/counter
        return result

And I will do sorting in view by sorted() and return as list.

It's work but I found that the speed of it is very very slow, so I would like to speed it up.

One way I think I could try is, save the computed weekly_score to the models (it already have field in model design) So that i could use order_by of models.

So the problem is, it is possible for me to do read and update at same view?

It's possbile for me do save/update action in BrandChartsSerializer ? or in same viewset (like calling two serializer in one view etc..)

Upvotes: 0

Views: 617

Answers (1)

Valery Ramusik
Valery Ramusik

Reputation: 1573

Serializer Save method is used for adding computed data :

def save(self, **kwargs):

    kwargs["weekly_score_on_model"] = calculate_weekly_score(self.validated_data)

    self.instance = super().save(**kwargs)
    return self.instance

Upvotes: 1

Related Questions