DjangoREST - How can I make my view/serializer more efficient on the server?

Viewed 42

I'm using a serializer to extract a specific object from my models, followed by using said object field as a parameter in URL's via requests.

I'm not getting any errors and everything is working fine, however I think it can be optimized better and be more efficient on the server.

serializer.py

class BucketListExtraDataSerializer(serializers.ModelSerializer):

    bucket_return = serializers.SerializerMethodField()
    bucket_sectors = serializers.SerializerMethodField()
    
    class Meta:
        model = Bucket
        fields = ('id','stock_list','bucket_return','bucket_sectors')

    def get_bucket_return(self, obj):
        print(obj.stock_list)
        if obj.stock_list:
            symbols_unicode = (','.join(map(str, obj.stock_list)))
            print(symbols_unicode)
            postgrest_urls = f"http://localhost:3000/rpc/bucketreturn?p_stocks=%7B{symbols_unicode}%7D"
            bucket_return = requests.get(postgrest_urls, headers={'Content-Type': 'application/json'}).json()
            return bucket_return
    def get_bucket_sectors(self, obj):
        if obj.stock_list:
            symbols_unicode = (','.join(map(str, obj.stock_list)))
            postgrest_urls = f"http://localhost:3000/rpc/bucketsectors?p_stocks=%7B{symbols_unicode}%7D"
            bucket_sectors = requests.get(postgrest_urls, headers={'Content-Type': 'application/json'}).json()
            return bucket_sectors

I don't think it's optimal having multiple SerializerMethodField()'s. Which makes me wonder if I should translate all the extra requests def_bucket_return + def_buket_sectors into a view instead.

I have doubts that in the future things can get really slow if a user has multiple objects.

view.py

class BucketListExtraData(generics.ListAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = BucketListExtraDataSerializer
    queryset = Bucket.objects.all()

Disclaimer: my localhost:3000 API which I'm sending requests too is not a bottleneck issue. Currently I'm specifically asking on how I set up my serializer and view.

Any recommendations on how I can optimize my serializer and view better to retrieve and display data quicker to the frontend?

1 Answers

You could make them properties on the model.

class Bucket(models.Model):
    ...

    @cached_property
    def symbols_unicode(self):
        if not self.stock_list:
            return None
        return (','.join(map(str, self.stock_list)))

    @cached_property
    def bucket_return(self):
        if not self.symbols_unicode:
            return None

        postgrest_urls = f"http://localhost:3000/rpc/bucketreturn?p_stocks=%7B{self.symbols_unicode}%7D"
        bucket_return = requests.get(postgrest_urls, headers={'Content-Type': 'application/json'}).json()
        return bucket_return


    @cached_property
    def bucket_sectors(self):
        if not self.symbols_unicode:
            return None

        postgrest_urls = f"http://localhost:3000/rpc/bucketsectors?p_stocks=%7B{self.symbols_unicode}%7D"
        bucket_sectors = requests.get(postgrest_urls, headers={'Content-Type': 'application/json'}).json()
        return bucket_sectors

Then your serializer can be something like this:

class BucketListExtraDataSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Bucket
        fields = ('id', 'stock_list', 'bucket_return', 'bucket_sectors')

Generally, I don't like to do much actual work in a SerializerMethodField, especially if that same logic will be used elsewhere.

This just shows how you can use attributes in serializers. It does not attempt to address the fact that you're making two external requests during serialization of a single object, but I don't think that's what you meant by optimizing in your question.

Related