From 0b516c412bbfdd8918efdc5edc2c137800ae5df7 Mon Sep 17 00:00:00 2001 From: Rohan Rangray Date: Fri, 29 May 2015 14:44:20 -0700 Subject: [PATCH] Added potential fix to get SQL expdecay sorting working on postgres --- flashcards/models.py | 21 ++++++++++++++++++++- flashcards/views.py | 6 +++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/flashcards/models.py b/flashcards/models.py index 0066f39..809fb61 100644 --- a/flashcards/models.py +++ b/flashcards/models.py @@ -16,6 +16,7 @@ from flashy.settings import QUARTER_START from simple_email_confirmation import SimpleEmailConfirmationUserMixin from fields import MaskField from cached_property import cached_property +from flashy.settings import IN_PRODUCTION # Hack to fix AbstractUser before subclassing it @@ -472,9 +473,27 @@ class WhitelistedAddress(Model): def __unicode__(self): return '%s whitelisted for %s' % (str(self.email), str(self.section)) + class JulianDay(Func): function = 'julianday' + template = '%(function)s(%(expressions)s)' def __init__(self, expression, **extra): - output = extra.pop('output_field', DateTimeField()) + output = extra.pop('output_field', FloatField()) super(JulianDay, self).__init__(expression, output_field=output, **extra) + + +class EncapsulateIntervalDay(Func): + function = 'EXTRACT' + template_postgres = "(((%(function)s(EPOCH FROM INTERVAL %(expressions)s) / 60) / 60) / 24)::integer" + arg_joiner = ' - ' + + def __init__(self, expression, **extra): + output = extra.pop('output_field', FloatField()) + super(EncapsulateIntervalDay, self).__init__(expression, output_field=output, **extra) + + +def interval_days(expression1, expression2): + if IN_PRODUCTION: + return EncapsulateIntervalDay(expression1, expression2) + return JulianDay(expression1) - JulianDay(expression2) diff --git a/flashcards/views.py b/flashcards/views.py index 1663587..04f8134 100644 --- a/flashcards/views.py +++ b/flashcards/views.py @@ -5,7 +5,7 @@ from django.utils.log import getLogger from flashcards.api import StandardResultsSetPagination, IsEnrolledInAssociatedSection, IsFlashcardReviewer, \ IsAuthenticatedAndConfirmed from flashcards.models import Section, User, Flashcard, FlashcardHide, UserFlashcard, UserFlashcardQuiz, \ - FlashcardAlreadyPulledException, FlashcardNotInDeckException + FlashcardAlreadyPulledException, FlashcardNotInDeckException, interval_days from flashcards.notifications import notify_new_card from flashcards.serializers import SectionSerializer, UserUpdateSerializer, RegistrationSerializer, UserSerializer, \ PasswordResetSerializer, PasswordResetRequestSerializer, EmailPasswordSerializer, FlashcardSerializer, \ @@ -406,8 +406,8 @@ class UserFlashcardQuizViewSet(GenericViewSet, CreateModelMixin, UpdateModelMixi quiz_filter = user_flashcard_filter.prefetch_related('userflashcardquiz_set').annotate( revise_count=Count('pk'), days_since=Case( - When(userflashcardquiz__when=None, then=Value(now(), output_field=DateTimeField())-F('pulled')), - default=Value(now(), output_field=DateTimeField())-Max('userflashcardquiz__when'), + When(userflashcardquiz__when=None, then=interval_days(Value(now(), output_field=DateTimeField()), F('pulled'))), + default=interval_days(Value(now(), output_field=DateTimeField()), Max('userflashcardquiz__when')), output_field=FloatField() ), retention_score=Case( -- 1.9.1