From e5ef3a61eff62e845bc747036d5e92a8cf659d48 Mon Sep 17 00:00:00 2001
From: janmax <j.michal@stud.uni-goettingen.de>
Date: Sun, 18 Feb 2018 19:28:01 +0100
Subject: [PATCH] Use prefetching on certain queries in order to boost response
 time

* This means a 2x - 10x performace boost especially for the student
  and the feedback endpoint
---
 core/serializers/subscription.py | 5 +----
 core/views/common_views.py       | 8 +++++++-
 core/views/feedback.py           | 9 ++++++---
 core/views/subscription.py       | 5 ++++-
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/core/serializers/subscription.py b/core/serializers/subscription.py
index adf3a54a..6509c754 100644
--- a/core/serializers/subscription.py
+++ b/core/serializers/subscription.py
@@ -47,10 +47,7 @@ class SubscriptionSerializer(DynamicFieldsModelSerializer):
     available = serializers.SerializerMethodField()
 
     def get_assignments(self, subscription):
-        queryset = TutorSubmissionAssignment.objects.filter(
-            subscription=subscription,
-            is_done=False
-        )
+        queryset = subscription.assignments.filter(is_done=False)
         serializer = AssignmentDetailSerializer(queryset, many=True)
         return serializer.data
 
diff --git a/core/views/common_views.py b/core/views/common_views.py
index cb109ffc..8aed85b1 100644
--- a/core/views/common_views.py
+++ b/core/views/common_views.py
@@ -54,7 +54,13 @@ class StudentSelfSubmissionsApiView(generics.ListAPIView):
 class StudentReviewerApiViewSet(viewsets.ReadOnlyModelViewSet):
     """ Gets a list of all students without individual submissions """
     permission_classes = (IsReviewer,)
-    queryset = StudentInfo.objects.all()
+    queryset = StudentInfo.objects\
+        .select_related('user')\
+        .select_related('exam')\
+        .prefetch_related('submissions')\
+        .prefetch_related('submissions__feedback')\
+        .prefetch_related('submissions__type')\
+        .all()
     serializer_class = StudentInfoSerializerForListView
 
 
diff --git a/core/views/feedback.py b/core/views/feedback.py
index 1eb11a05..6735d167 100644
--- a/core/views/feedback.py
+++ b/core/views/feedback.py
@@ -16,7 +16,10 @@ class FeedbackApiView(
         viewsets.GenericViewSet):
     """ Gets a list of an individual exam by Id if provided """
     permission_classes = (permissions.IsTutorOrReviewer,)
-    queryset = models.Feedback.objects.all()
+    queryset = models.Feedback.objects\
+        .select_related('of_submission')\
+        .select_related('of_submission__type')\
+        .all()
     serializer_class = serializers.FeedbackSerializer
     lookup_field = 'of_submission__pk'
     lookup_url_kwarg = 'submission_pk'
@@ -69,10 +72,10 @@ class FeedbackApiView(
 
     def get_queryset(self):
         if self.request.user.is_reviewer():
-            return models.Feedback.objects.all()
+            return self.queryset.all()
         else:
             # only return feedback that the requesting user has worked on
-            return models.Feedback.objects.filter(
+            return self.queryset.filter(
                 of_submission__assignments__subscription__owner=self.request.user  # noqa
             )
 
diff --git a/core/views/subscription.py b/core/views/subscription.py
index 2e00c5ca..25ebafb9 100644
--- a/core/views/subscription.py
+++ b/core/views/subscription.py
@@ -20,9 +20,12 @@ class SubscriptionApiViewSet(
         viewsets.GenericViewSet):
     permission_classes = (permissions.IsTutorOrReviewer,)
     serializer_class = serializers.SubscriptionSerializer
+    queryset = models.SubmissionSubscription.objects\
+        .prefetch_related('assignments')\
+        .select_related('owner')
 
     def get_queryset(self):
-        return models.SubmissionSubscription.objects.filter(
+        return self.queryset.filter(
             owner=self.request.user,
             deactivated=False
         )
-- 
GitLab