Skip to content

Commit

Permalink
Replace use of RawSQL with functions.
Browse files Browse the repository at this point in the history
As Django 4.2 does not group on RawSQL automatically any more.
  • Loading branch information
dracos committed May 12, 2024
1 parent f2b0675 commit 51b18d0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
20 changes: 13 additions & 7 deletions productions/objshow.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
from datetime import datetime
from functools import partial
from django.core.paginator import Paginator, InvalidPage
from django.db.models import Q, Max
from django.db.models.expressions import RawSQL
from django.db.models import Q, Max, Min, Case, When, F
from django.db.models.functions import Coalesce
# from django.db.models.expressions import RawSQL
from django.http import Http404
from django.shortcuts import render
from .models import Production, Part, ProductionCompany
from plays.models import Play
from places.models import Place
from people.models import Person
from aggregates import Concatenate
from fields import ApproximateDateField


# object is Place, Person, Play, or ProductionCompany
Expand All @@ -33,10 +35,13 @@ def productions_filter(object, type, date_filter):
else:
raise Exception('Strange call to productions_filter')

end_date_field = f"{annotate_extra}end_date"
press_date_field = f"{annotate_extra}press_date"
start_date_field = f"{annotate_extra}start_date"
o = o.annotate(
max_end_date=Max(annotate_extra + 'end_date'),
max_press_date=Max(annotate_extra + 'press_date'),
max_start_date=Max(annotate_extra + 'start_date')
max_end_date=Max(end_date_field),
max_press_date=Max(press_date_field),
max_start_date=Max(start_date_field)
)
filter = (~Q(max_end_date='') & Q(max_end_date__lt=now)) | Q(max_end_date='', max_press_date__lt=now) | Q(max_end_date='', max_press_date__isnull=True, max_start_date__lt=now)
if filter_extra:
Expand All @@ -54,9 +59,10 @@ def productions_filter(object, type, date_filter):
o = o.annotate(part__role__concatenate=Concatenate('part__role', distinct=True))

if date_filter == 'past':
return o.annotate(best_date=RawSQL('MIN(IFNULL(productions_place.press_date, IF(productions_place.end_date!="", productions_place.end_date, productions_place.start_date)))', ())).order_by('-best_date')
return o.annotate(best_date=Min(Coalesce(press_date_field, Case(When(**{end_date_field: ""}, then=F(start_date_field)), default=F(end_date_field)), output_field=ApproximateDateField()))).order_by('-best_date')
# return o.annotate(best_date=Min(RawSQL('IFNULL(productions_place.press_date, IF(productions_place.end_date!="", productions_place.end_date, productions_place.start_date))', ()))).order_by('-best_date')
else:
return o.order_by(annotate_extra + 'start_date', annotate_extra + 'press_date')
return o.order_by(start_date_field, press_date_field)


def _prods_one_way(fltr, object, sort_order):
Expand Down
9 changes: 6 additions & 3 deletions profiles/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
from django.contrib.auth.views import LoginView as DjangoLoginView
from django.shortcuts import render

from django.db.models import Q, Min
from django.db.models.expressions import RawSQL
from django.db.models import Q, Min, Case, When, F
from django.db.models.functions import Coalesce
# from django.db.models.expressions import RawSQL
from django.contrib.contenttypes.models import ContentType
from django_comments.models import Comment
from django.contrib import messages
Expand All @@ -17,6 +18,7 @@
from utils import int_to_base32, base32_to_int
from reversion.models import Revision
from .models import User
from fields import ApproximateDateField


@login_required
Expand Down Expand Up @@ -47,7 +49,8 @@ def profile(request, username):
latest.append(versions)

# Min bit isn't needed except to make sure the GROUP BY gets added
seen = user.visit_set.annotate(min_press_date=Min('production__place__press_date')).annotate(best_date=RawSQL('MIN(IFNULL(productions_place.press_date, IF(productions_place.end_date!="", productions_place.end_date, productions_place.start_date)))', ())).order_by('-best_date')
seen = user.visit_set.annotate(min_press_date=Min('production__place__press_date')).annotate(best_date=Min(Coalesce("production__place__press_date", Case(When(production__place__end_date="", then=F("production__place__start_date")), default=F("production__place__end_date")), output_field=ApproximateDateField()))).order_by('-best_date')
# seen = user.visit_set.annotate(min_press_date=Min('production__place__press_date')).annotate(best_date=Min(RawSQL('IFNULL(productions_place.press_date, IF(productions_place.end_date!="", productions_place.end_date, productions_place.start_date))', ()))).order_by('-best_date')

return render(request, 'profile.html', {
'view': user,
Expand Down

0 comments on commit 51b18d0

Please sign in to comment.