Commit 68485dd8 by J. Cliff Dyer

Reduce query counts

parent f9d4d6a2
......@@ -14,7 +14,7 @@ from django.db import IntegrityError, DatabaseError
from dogapi import dog_stats_api
from submissions.serializers import (
SubmissionSerializer, StudentItemSerializer, ScoreSerializer
SubmissionSerializer, StudentItemSerializer, ScoreSerializer, UnannotatedScoreSerializer
)
from submissions.models import Submission, StudentItem, Score, ScoreSummary, ScoreAnnotation, score_set, score_reset
......@@ -626,8 +626,7 @@ def get_score(student_item):
def get_scores(course_id, student_id):
"""
Return a dict mapping item_ids -> [ScoreSerializer(ScoreSummary)].
"""Return a dict mapping item_ids -> [ScoreSerializer(ScoreSummary)].
This method would be used by an LMS to find all the scores for a given
student in a given course.
......@@ -655,7 +654,7 @@ def get_scores(course_id, student_id):
score_summaries = ScoreSummary.objects.filter(
student_item__course_id=course_id,
student_item__student_id=student_id,
).select_related('latest', 'student_item')
).select_related('latest', 'latest__submission', 'student_item')
except DatabaseError:
msg = u"Could not fetch scores for course {}, student {}".format(
course_id, student_id
......@@ -663,7 +662,7 @@ def get_scores(course_id, student_id):
logger.exception(msg)
raise SubmissionInternalError(msg)
scores = {
summary.student_item.item_id: ScoreSerializer(summary.latest).data
summary.student_item.item_id: UnannotatedScoreSerializer(summary.latest).data
for summary in score_summaries if not summary.latest.is_hidden()
}
return scores
......
......@@ -96,12 +96,31 @@ class ScoreAnnotationSerializer(serializers.ModelSerializer):
)
class ScoreSerializer(serializers.ModelSerializer):
class UnannotatedScoreSerializer(serializers.ModelSerializer):
# Ensure that the created_at datetime is not converted to a string.
created_at = DateTimeField(format=None, required=False)
class Meta:
model = Score
fields = (
'student_item',
'submission',
'points_earned',
'points_possible',
'created_at',
# Computed
'submission_uuid',
)
class ScoreSerializer(serializers.ModelSerializer):
# Ensure that the created_at datetime is not converted to a string.
created_at = DateTimeField(format=None, required=False)
annotations = serializers.SerializerMethodField()
def get_annotations(self, obj):
"""
Inspect ScoreAnnotations to attach all relevant annotations.
......
......@@ -363,6 +363,7 @@ class TestSubmissionsApi(TestCase):
student_item['student_id'] = None
self.assertIs(api.get_score(student_item), None)
@freeze_time(datetime.datetime.now().replace(tzinfo=pytz.UTC))
def test_get_scores(self):
student_item = copy.deepcopy(STUDENT_ITEM)
student_item["course_id"] = "get_scores_course"
......@@ -388,14 +389,35 @@ class TestSubmissionsApi(TestCase):
scores = api.get_scores(
student_item["course_id"], student_item["student_id"]
)
self.assertEqual(
scores,
{
u"i4x://a/b/c/s1": (2, 5),
u"i4x://a/b/c/s2": (0, 10),
u"i4x://a/b/c/s3": (4, 4),
}
)
self.assertEqual(
scores,
{
u'i4x://a/b/c/s1': {
'created_at': datetime.datetime.now(),
'points_earned': 2,
'points_possible': 5,
'student_item': 1,
'submission': 1,
'submission_uuid': s1['uuid'],
},
u'i4x://a/b/c/s2': {
'created_at': datetime.datetime.now(),
'points_earned': 0,
'points_possible': 10,
'student_item': 2,
'submission': 2,
'submission_uuid': s2['uuid'],
},
u'i4x://a/b/c/s3': {
'created_at': datetime.datetime.now(),
'points_earned': 4,
'points_possible': 4,
'student_item': 3,
'submission': 3,
'submission_uuid': s3['uuid'],
},
}
)
def test_get_top_submissions(self):
student_item_1 = copy.deepcopy(STUDENT_ITEM)
......
......@@ -137,7 +137,8 @@ class TestResetScore(TestCase):
scores = sub_api.get_scores(self.STUDENT_ITEM['course_id'], self.STUDENT_ITEM['student_id'])
self.assertIn(self.STUDENT_ITEM['item_id'], scores)
self.assertEqual(scores[self.STUDENT_ITEM['item_id']], (3, 4))
item_score = scores[self.STUDENT_ITEM['item_id']]
self.assertEqual((item_score['points_earned'], item_score['points_possible']), (3, 4))
def test_reset_then_get_score_for_submission(self):
# Create a submission for the student and score it
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment