Commit e9b6b467 authored by fred's avatar fred

performance: refactor code shared by episode and emission into a mixin

Cuts down a "Panik sur la ville" episode page from 585 to 23 queries.
parent 23784a43
...@@ -18,18 +18,14 @@ from emissions.models import Category, Emission, Episode, Diffusion, SoundFile, ...@@ -18,18 +18,14 @@ from emissions.models import Category, Emission, Episode, Diffusion, SoundFile,
from emissions.utils import whatsonair, period_program from emissions.utils import whatsonair, period_program
class EmissionDetailView(DetailView): class EmissionMixin:
model = Emission def get_emission_context(self, emission):
context = {}
def get_context_data(self, **kwargs):
context = super(EmissionDetailView, self).get_context_data(**kwargs)
context['sectionName'] = "Emissions"
context['schedules'] = Schedule.objects.select_related().filter(emission=self.object).order_by('datetime')
# get all episodes, with an additional attribute to get the date of # get all episodes, with an additional attribute to get the date of
# their first diffusion # their first diffusion
context['episodes'] = \ context['episodes'] = \
Episode.objects.select_related().filter(emission=self.object Episode.objects.select_related().filter(emission=emission
).extra(select={ ).extra(select={
'first_diffusion': 'emissions_diffusion.datetime', 'first_diffusion': 'emissions_diffusion.datetime',
}, },
...@@ -43,7 +39,7 @@ class EmissionDetailView(DetailView): ...@@ -43,7 +39,7 @@ class EmissionDetailView(DetailView):
# get all related soundfiles in a single query # get all related soundfiles in a single query
soundfiles = {} soundfiles = {}
for soundfile in SoundFile.objects.select_related().filter(podcastable=True, for soundfile in SoundFile.objects.select_related().filter(podcastable=True,
fragment=False, episode__emission=self.object): fragment=False, episode__emission=emission):
soundfiles[soundfile.episode_id] = soundfile soundfiles[soundfile.episode_id] = soundfile
# replace dynamic property by a static attribute, to avoid database # replace dynamic property by a static attribute, to avoid database
...@@ -52,41 +48,30 @@ class EmissionDetailView(DetailView): ...@@ -52,41 +48,30 @@ class EmissionDetailView(DetailView):
episode.main_sound = soundfiles.get(episode.id) episode.main_sound = soundfiles.get(episode.id)
return context return context
class EmissionDetailView(DetailView, EmissionMixin):
model = Emission
def get_context_data(self, **kwargs):
context = super(EmissionDetailView, self).get_context_data(**kwargs)
context['sectionName'] = "Emissions"
context['schedules'] = Schedule.objects.select_related().filter(emission=self.object).order_by('datetime')
context.update(self.get_emission_context(self.object))
return context
emission = EmissionDetailView.as_view() emission = EmissionDetailView.as_view()
class EpisodeDetailView(DetailView): class EpisodeDetailView(DetailView, EmissionMixin):
model = Episode model = Episode
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(EpisodeDetailView, self).get_context_data(**kwargs) context = super(EpisodeDetailView, self).get_context_data(**kwargs)
context['sectionName'] = "Emissions" context['sectionName'] = "Emissions"
context['diffusions'] = Diffusion.objects.filter(episode=self.object.id) context['diffusions'] = Diffusion.objects.select_related().filter(episode=self.object.id)
context['soundfiles'] = SoundFile.objects.filter(episode=self.object.id) context['soundfiles'] = SoundFile.objects.select_related().filter(episode=self.object.id)
context['emission'] = Emission.objects.get(slug=self.kwargs.get('emission_slug')) context['emission'] = Emission.objects.get(slug=self.kwargs.get('emission_slug'))
# get all episodes, with an additional attribute to get the date of context.update(self.get_emission_context(context['emission']))
# their first diffusion
context['episodes'] = \
Episode.objects.filter(emission=context['emission']
).extra(select={
'first_diffusion': 'emissions_diffusion.datetime',
},
select_params=(False, True),
where=['''datetime = (SELECT MIN(datetime)
FROM emissions_diffusion
WHERE episode_id = emissions_episode.id)'''],
tables=['emissions_diffusion'],
).order_by('-first_diffusion')
# get all related soundfiles in a single query
soundfiles = {}
for soundfile in SoundFile.objects.filter(podcastable=True,
fragment=False, episode__emission=Emission.objects.get(slug=self.kwargs.get('emission_slug'))):
soundfiles[soundfile.episode_id] = soundfile
# replace dynamic property by a static attribute, to avoid database
# lookups
for episode in context['episodes']:
episode.main_sound = soundfiles.get(episode.id)
return context return context
episode = EpisodeDetailView.as_view() episode = EpisodeDetailView.as_view()
......
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