From 94b54a0ef2aa77cf113a20d09d75fe178339a34a Mon Sep 17 00:00:00 2001 From: Evert Date: Sat, 11 Nov 2017 10:03:06 +0200 Subject: [PATCH] Show - Use .annotate for submissions with votes and their ordering --- Show/views.py | 63 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/Show/views.py b/Show/views.py index ad83970..2c9d158 100644 --- a/Show/views.py +++ b/Show/views.py @@ -3,8 +3,10 @@ from django.shortcuts import render from django.views import View from django.views.generic.base import TemplateView from django.conf import settings +from django.http import Http404 from django.http import HttpResponse from django.http import HttpResponseRedirect +from django.db.models import Case, When, Value, IntegerField, Count, F from LandingPage.models import Show from LandingPage.models import Season @@ -13,35 +15,66 @@ from LandingPage.models import Submission # Create your views here. +# Index page of a show class IndexView(TemplateView): template_name = "show.html" def get_context_data(self, abbreviation, **kwargs): ctx = super().get_context_data() - ctx['show'] = Show.objects.filter(abbr=abbreviation).first() - ctx['seasons'] = Season.objects.filter(show=ctx['show']) - ctx['episodes'] = Episode.objects.filter(show=ctx['show']).count() + + # Get show by abbreviation, add episode count to the show and return only the first object + show = Show.objects.filter(abbr=abbreviation).annotate(episode_count=Count('episodes')).first() + + # 404 + if not show: + raise Http404("Show does not exist") + + # Get all seasons of the show and annotate episode counts onto them + seasons = show.seasons.all().annotate(episode_count=Count('episodes')) + + # Add fields to context + ctx['show'] = show + ctx['seasons'] = seasons + return ctx +# Episodes page of a show class EpisodeView(TemplateView): template_name = "episode.html" def get_context_data(self, abbreviation, season, episode, **kwargs): ctx = super().get_context_data() - ctx['show'] = Show.objects.filter(abbr=abbreviation).first() - ctx['episode'] = Episode.objects.filter(show=ctx['show'],episode=episode).first() + + # Get show by abbreviation + show = Show.objects.filter(abbr=abbreviation).first() + + # Get episode by season and episode number + episode = Episode.objects.filter(show=show,episode=episode).first() + + # 404's + if not show: + raise Http404("Show does not exist") - if not ctx['episode']: - return ctx + if not episode: + raise Http404("Episode does not exist") - # If you're smarter than me, maybe you can compress the next 8 lines into fewer ones by some django magic I'm not aware of - submissions = ctx['episode'].submissions.all() + # I aknowledge that this is a mess. A functional mess. But a mess nonetheless. Hey, that rhymed! + submissions = episode.submissions.annotate( + positives=Count( + Case( + When( + votes__positive=True, + then=Value(1) + ) + ) + ), + negatives=Count('votes') - F('positives'), + score=F('positives') - F('negatives') + ).order_by('-score') - for sbm in submissions: - sbm.positives = sbm.votes.filter(positive=True).count() - sbm.negatives = sbm.votes.count() - sbm.positives - - # sorts by "score", TODO: less bullshit - ctx['submissions'] = reversed(sorted(submissions, key=lambda x: x.positives - x.negatives)) + # Add fields to context + ctx['show'] = show + ctx['episode'] = episode + ctx['submissions'] = submissions return ctx