django REST Performance

Django REST Framework

So, I was building a Forum for my client using django + Angularjs, while building the front end with test data, I notice that DRF using a whooping 23 queries for 2 post and 1 replies!

Yes, its a bit too much..and its increasing with more post and replies. After I made a few reading, I realize that DRF left us to do the query improvement ourself.

So, at first my serializer are looking like this ;

class KomenHome(serializers.ModelSerializer):
    user = serializers.StringRelatedField(read_only=True)

    class Meta:
        model = Komen
        fields = ('ubah','user')

class TopikHome(serializers.ModelSerializer):
    replytopik = serializers.SerializerMethodField('get_item')
    user = serializers.StringRelatedField()

    class Meta:
        model = Topik
        fields = ('tajuk','user','ubah','replytopik')

    def get_item(self, topik):
        item = Komen.objects.filter(topik=topik)[:1]
        serializers = KomenHome(instance=item, many=True)

class ForumHome(serializers.ModelSerializer):
    topik_set = serializers.SerializerMethodField('get_item')
    topik_count = serializers.IntegerField(source='topik_set.count',read_only=True)
    class Meta:
        model = Kategori
        fields = ('id','tajuk','desc','topik_count,'topik_set')
    def get_item(self, kategori):
        item = Topik.objects.filter(kategori=kategori)[:3]
        serializers = TopikHome(instance=item, many=True)


and api :


class ForumHomeApi(generics.ListAPIView):
    queryset = Kategori.objects.all()
    serializer_class = ForumHome
    pagination_class = PaginateBesar

then I make the 'normal' queryset adjustment on API :

def get_queryset(self):
    return Kategori.objects.select_related().all().prefetch_related('topik_set__replytopik','topik_set__user','topik_set__replytopik__user')

and i changed this on serializer :


topik_set = TopikHome(many=True) 

for both of my topichome and replyhome serializer.


That adjustment drop my queries to 8! Best of all, it doesnt increase with additional post.

But, I still need to limit those queryset for Topics to 3 and latest Replies to 1.

So I decided to to those queryset limit in my model Manager.


def homekomen(self):
    return self.replytopik.all()[:1]

for both Topic and Reply models and made these adjustment to my serializer :

topik_set = TopikHome(source='hometopik',many=True)

And Yeah, that didnt increase any queries..What about my topic count?

I customized my queryset in my API like this :

return Kategori.objects.select_related().all().prefetch_related('topik_set__replytopik','topik_set__user','topik_set__replytopik__user').annotate(post=Count('topik'),repl=Count('topik__replytopik'))

and add this instead to my serializer :

post = serializers.IntegerField()
repl = serializers.IntegerField()

and still my Query doesnt increase!

Share this Post:

Related Posts: