Show - Use .annotate for submissions with votes and their ordering

This commit is contained in:
Evert Prants 2017-11-11 10:03:06 +02:00
parent 4adab93c3a
commit 94b54a0ef2
Signed by: evert
GPG Key ID: 1688DA83D222D0B5

View File

@ -3,8 +3,10 @@ from django.shortcuts import render
from django.views import View from django.views import View
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django.conf import settings from django.conf import settings
from django.http import Http404
from django.http import HttpResponse from django.http import HttpResponse
from django.http import HttpResponseRedirect 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 Show
from LandingPage.models import Season from LandingPage.models import Season
@ -13,35 +15,66 @@ from LandingPage.models import Submission
# Create your views here. # Create your views here.
# Index page of a show
class IndexView(TemplateView): class IndexView(TemplateView):
template_name = "show.html" template_name = "show.html"
def get_context_data(self, abbreviation, **kwargs): def get_context_data(self, abbreviation, **kwargs):
ctx = super().get_context_data() ctx = super().get_context_data()
ctx['show'] = Show.objects.filter(abbr=abbreviation).first()
ctx['seasons'] = Season.objects.filter(show=ctx['show']) # Get show by abbreviation, add episode count to the show and return only the first object
ctx['episodes'] = Episode.objects.filter(show=ctx['show']).count() 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 return ctx
# Episodes page of a show
class EpisodeView(TemplateView): class EpisodeView(TemplateView):
template_name = "episode.html" template_name = "episode.html"
def get_context_data(self, abbreviation, season, episode, **kwargs): def get_context_data(self, abbreviation, season, episode, **kwargs):
ctx = super().get_context_data() ctx = super().get_context_data()
ctx['show'] = Show.objects.filter(abbr=abbreviation).first()
ctx['episode'] = Episode.objects.filter(show=ctx['show'],episode=episode).first()
if not ctx['episode']: # Get show by abbreviation
return ctx show = Show.objects.filter(abbr=abbreviation).first()
# 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 # Get episode by season and episode number
submissions = ctx['episode'].submissions.all() episode = Episode.objects.filter(show=show,episode=episode).first()
for sbm in submissions: # 404's
sbm.positives = sbm.votes.filter(positive=True).count() if not show:
sbm.negatives = sbm.votes.count() - sbm.positives raise Http404("Show does not exist")
# sorts by "score", TODO: less bullshit if not episode:
ctx['submissions'] = reversed(sorted(submissions, key=lambda x: x.positives - x.negatives)) raise Http404("Episode does not exist")
# 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')
# Add fields to context
ctx['show'] = show
ctx['episode'] = episode
ctx['submissions'] = submissions
return ctx return ctx