From 08242a3b95447ae382b4522c7fe44926daf2aa4e Mon Sep 17 00:00:00 2001 From: Szabo Zoltan Date: Mon, 1 Jul 2024 18:29:10 +0200 Subject: [PATCH 1/2] Fix multiple user queries n+1 issue --- api/drf_views.py | 20 ++++++++++++++++++-- api/serializers.py | 10 ++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/api/drf_views.py b/api/drf_views.py index 40b14bad4..f0ee5bb6d 100644 --- a/api/drf_views.py +++ b/api/drf_views.py @@ -1,6 +1,6 @@ from datetime import timedelta -from django.contrib.auth.models import User +from django.contrib.auth.models import Group, User from django.db import models from django.db.models import ( Avg, @@ -1297,7 +1297,23 @@ class UsersViewset(viewsets.ReadOnlyModelViewSet): filterset_class = UserFilterSet def get_queryset(self): - return User.objects.filter(is_active=True) + + return ( + User.objects.select_related( + "profile", + "profile__country", + ) + .prefetch_related("subscription") + .annotate( + is_ifrc_admin=models.Exists( + Group.objects.filter( + name__iexact="IFRC Admins", + user=OuterRef("pk"), + ) + ) + ) + .filter(is_active=True) + ) class GlobalEnumView(APIView): diff --git a/api/serializers.py b/api/serializers.py index 8bce833db..152acb9e6 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -1616,7 +1616,7 @@ class Meta: class UserSerializer(ModelSerializer): profile = ProfileSerializer() subscription = MiniSubscriptionSerializer(many=True) - is_ifrc_admin = serializers.SerializerMethodField() + is_ifrc_admin = serializers.BooleanField(read_only=True) class Meta: model = User @@ -1654,9 +1654,11 @@ def update(self, instance, validated_data): instance.save() return instance - @staticmethod - def get_is_ifrc_admin(obj) -> bool: - return obj.groups.filter(name__iexact="IFRC Admins").exists() + +# Instead of the below method we use the serializer's annotate tag: +# @staticmethod +# def get_is_ifrc_admin(obj) -> bool: +# return obj.groups.filter(name__iexact="IFRC Admins").exists() class UserNameSerializer(UserSerializer): From c1cba5002a148496fcbefeaebcfba5d7b0697e84 Mon Sep 17 00:00:00 2001 From: Szabo Zoltan Date: Mon, 1 Jul 2024 18:43:38 +0200 Subject: [PATCH 2/2] Fix per-formquestion query n+1 issue --- per/drf_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/per/drf_views.py b/per/drf_views.py index b736e9eba..94199914f 100644 --- a/per/drf_views.py +++ b/per/drf_views.py @@ -193,7 +193,7 @@ def get_queryset(self): return ( FormQuestion.objects.all() .order_by("component__component_num", "question_num", "question") - .select_related("component") + .select_related("component", "component__area") .prefetch_related("answers") )