Cache the total and filtered counts in the gradebook API.

This commit is contained in:
Dave St.Germain
2019-07-26 14:10:44 -04:00
parent f668e0f53a
commit 9bd0d915dc

View File

@@ -3,12 +3,14 @@ Defines an endpoint for gradebook data related to a course.
""" """
from __future__ import absolute_import from __future__ import absolute_import
import hashlib
import logging import logging
from collections import namedtuple from collections import namedtuple
from contextlib import contextmanager from contextlib import contextmanager
from functools import wraps from functools import wraps
import six import six
from django.core.cache import cache
from django.db.models import Q from django.db.models import Q
from django.urls import reverse from django.urls import reverse
from opaque_keys import InvalidKeyError from opaque_keys import InvalidKeyError
@@ -567,6 +569,22 @@ class GradebookView(GradeViewMixin, PaginatedAPIView):
serializer = StudentGradebookEntrySerializer(entries, many=True) serializer = StudentGradebookEntrySerializer(entries, many=True)
return self.get_paginated_response(serializer.data, **users_counts) return self.get_paginated_response(serializer.data, **users_counts)
def _get_user_count(self, query_args, cache_time=3600):
"""
Return the user count for the given query arguments to CourseEnrollment.
caches the count for cache_time seconds.
"""
hasher = hashlib.md5()
for arg in query_args:
hasher.update(bytes(arg))
cache_key = 'usercount.%s' % hasher.hexdigest()
user_count = cache.get(cache_key, None)
if user_count is None:
user_count = CourseEnrollment.objects.filter(*query_args).count()
cache.set(cache_key, user_count, cache_time)
return user_count
def _get_users_counts(self, course_key, course_enrollment_filters): def _get_users_counts(self, course_key, course_enrollment_filters):
""" """
Return a dictionary containing data about the total number of users and total number Return a dictionary containing data about the total number of users and total number
@@ -587,7 +605,7 @@ class GradebookView(GradeViewMixin, PaginatedAPIView):
Q(course_id=course_key) & Q(is_active=True) Q(course_id=course_key) & Q(is_active=True)
] ]
total_users_count = CourseEnrollment.objects.filter(*filter_args).count() total_users_count = self._get_user_count(filter_args)
filter_args.extend(course_enrollment_filters or []) filter_args.extend(course_enrollment_filters or [])
@@ -595,7 +613,7 @@ class GradebookView(GradeViewMixin, PaginatedAPIView):
filtered_users_count = ( filtered_users_count = (
total_users_count total_users_count
if not course_enrollment_filters if not course_enrollment_filters
else CourseEnrollment.objects.filter(*filter_args).count() else self._get_user_count(filter_args)
) )
return { return {