From 194658c64de0c6f61aa7b7508d36bf0c3ac6be47 Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Wed, 24 Feb 2021 00:54:39 +0100 Subject: [PATCH] Vysledkovka | dalsi pokusy o optimalizace --- seminar/models.py | 12 ++++++++---- seminar/utils.py | 24 ++++++++++++------------ seminar/views/views_all.py | 8 ++++---- seminar/views/vysledkovka.py | 15 +++++++++------ 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index fd34773f..b85711e5 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -18,6 +18,7 @@ from django.contrib.contenttypes.models import ContentType from django.utils.text import get_valid_filename from imagekit.models import ImageSpecField, ProcessedImageField from imagekit.processors import ResizeToFit, Transpose +from django.utils.functional import cached_property from django_countries.fields import CountryField from solo.models import SingletonModel @@ -855,10 +856,11 @@ class Problem(SeminarModelBase,PolymorphicModel): return self.nazev # Implicitini implementace, jednotlivé dědící třídy si přepíšou + @cached_property def kod_v_rocniku(self): if self.stav == 'zadany': if self.nadproblem: - return self.nadproblem.kod_v_rocniku()+".{}".format(self.kod) + return self.nadproblem.kod_v_rocniku+".{}".format(self.kod) return str(self.kod) return '' @@ -927,10 +929,11 @@ class Tema(Problem): abstrakt = models.TextField('Abstrakt na rozcestník', blank=True) obrazek = models.ImageField('Obrázek na rozcestník', null=True) + @cached_property def kod_v_rocniku(self): if self.stav == 'zadany': if self.nadproblem: - return self.nadproblem.kod_v_rocniku()+".t{}".format(self.kod) + return self.nadproblem.kod_v_rocniku+".t{}".format(self.kod) return "t{}".format(self.kod) return '' @@ -963,7 +966,7 @@ class Clanek(Problem): if self.stav == 'zadany': # Nemělo by být potřeba # if self.nadproblem: -# return self.nadproblem.kod_v_rocniku()+".c{}".format(self.kod) +# return self.nadproblem.kod_v_rocniku+".c{}".format(self.kod) return "c{}".format(self.kod) return '' @@ -1020,11 +1023,12 @@ class Uloha(Problem): # UlohaZadaniNode # UlohaVzorakNode + @cached_property def kod_v_rocniku(self): if self.stav == 'zadany': name="{}.u{}".format(self.cislo_zadani.poradi,self.kod) if self.nadproblem: - return self.nadproblem.kod_v_rocniku()+name + return self.nadproblem.kod_v_rocniku+name return name return '' diff --git a/seminar/utils.py b/seminar/utils.py index e3d87020..19815cd8 100644 --- a/seminar/utils.py +++ b/seminar/utils.py @@ -249,21 +249,22 @@ def hlavni_problemy_rocniku(rocnik, jen_verejne=True): hlavni_problemy.append(problem) hlavni_problemy_set = set(hlavni_problemy) hlavni_problemy = list(hlavni_problemy_set) - hlavni_problemy.sort(key=lambda k:k.kod_v_rocniku()) # setřídit podle pořadí + hlavni_problemy.sort(key=lambda k:k.kod_v_rocniku) # setřídit podle pořadí return hlavni_problemy def problemy_cisla(cislo): """ Vrátí seznam všech problémů s body v daném čísle. """ - hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all() + return m.Problem.objects.filter(hodnoceni__in = m.Hodnoceni.objects.filter(cislo_body = cislo)).distinct().select_related('nadproblem') + +# hodnoceni = cislo.hodnoceni.select_related('problem').all() # hodnocení, která se vážou k danému číslu - reseni = [h.reseni for h in hodnoceni] - problemy = [h.problem for h in hodnoceni] - problemy_set = set(problemy) # chceme každý problém unikátně, - problemy = (list(problemy_set)) # převedení na množinu a zpět to zaručí +# problemy = [h.problem for h in hodnoceni] +# problemy_set = set(problemy) # chceme každý problém unikátně, +# problemy = (list(problemy_set)) # převedení na množinu a zpět to zaručí - return problemy +# return problemy def hlavni_problemy_cisla(cislo, problemy=None): @@ -273,14 +274,13 @@ def hlavni_problemy_cisla(cislo, problemy=None): # hlavní problémy čísla # (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) - hlavni_problemy = [] + hlavni_problemy = set() for p in problemy: - hlavni_problemy.append(hlavni_problem(p)) + hlavni_problemy.add(hlavni_problem(p)) # zunikátnění - hlavni_problemy_set = set(hlavni_problemy) - hlavni_problemy = list(hlavni_problemy_set) - hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku()) # setřídit podle t1, t2, c3, ... + hlavni_problemy = list(hlavni_problemy) + hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku) # setřídit podle t1, t2, c3, ... return hlavni_problemy diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index d7c7d041..dabfbc2b 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -522,7 +522,7 @@ def spravne_novinky(request): user = request.user # Využíváme líné vyhodnocování QuerySetů qs = Novinky.objects.all() - if not user.je_org(): + if not user.je_org: qs = qs.filter(zverejneno=True) return qs.order_by('-datum') @@ -654,7 +654,7 @@ class RocnikView(generic.DetailView): # vysledkovka = True zajistí vykreslení, # zkontrolovat, kdy se má a nemá vykreslovat context['vysledkovka'] = True - if self.request.user.je_org(): + if self.request.user.je_org: context['cisla_s_neverejnymi'] = cisla_rocniku(context["rocnik"], jen_verejne=False) context['radky_vysledkovky_s_neverejnymi'] = vysledkovka_rocniku(context["rocnik"], jen_verejne=False) context['hlavni_problemy_v_rocniku_s_neverejnymi'] = hlavni_problemy_rocniku(context["rocnik"], jen_verejne=False) @@ -685,7 +685,7 @@ class ProblemView(generic.DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Musí se používat context['object'], protože nevíme, jestli dostaneme úložku, téma, článek, .... a tyhle věci vyrábějí různé klíče. - if not context['object'].verejne() and not self.request.user.je_org(): + if not context['object'].verejne() and not self.request.user.je_org: raise PermissionDenied() if isinstance(context['object'], Clanek): context['reseni'] = Reseni.objects.filter(problem=context['object']).select_related('resitel').order_by('resitel__prijmeni') @@ -969,7 +969,7 @@ class ClankyResitelView(generic.ListView): queryset = [] skupiny_clanku = group_by_rocnik(clanky) for skupina in skupiny_clanku: - skupina.sort(key=lambda clanek: clanek.kod_v_rocniku()) + skupina.sort(key=lambda clanek: clanek.kod_v_rocniku) for clanek in skupina: queryset.append(clanek) return queryset diff --git a/seminar/views/vysledkovka.py b/seminar/views/vysledkovka.py index bbdb067f..637a3398 100644 --- a/seminar/views/vysledkovka.py +++ b/seminar/views/vysledkovka.py @@ -242,13 +242,11 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): hlavni_problemy = hlavni_problemy_cisla(cislo) def ne_clanek_ne_konfera(problem): - return not(isinstance(problem.get_real_instance(), m.Clanek) or isinstance(problem.get_real_instance(), m.Konfera)) + inst = problem.get_real_instance() + return not(isinstance(inst, m.Clanek) or isinstance(inst, m.Konfera)) temata_a_spol = list(filter(ne_clanek_ne_konfera, hlavni_problemy)) - def cosi(problem): - return problem.id - hlavni_problemy_slovnik = {} for hp in temata_a_spol: hlavni_problemy_slovnik[hp.id] = {} @@ -389,7 +387,6 @@ def vysledkovka_cisla(cislo, context=None): # řešitelé setřídění podle bodů za číslo sestupně setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn] - setrizeni_resitele = [m.Resitel.objects.get(id=i) for i in setrizeni_resitele_id] # spočítáme pořadí řešitelů setrizeni_resitele_body = [dvojice[1] for dvojice in resitel_rocnikbody_sezn] @@ -400,6 +397,7 @@ def vysledkovka_cisla(cislo, context=None): i = 0 def ne_clanek_ne_konfera(problem): + return not(isinstance(problem.get_real_instance(), m.Clanek) or isinstance(problem.get_real_instance(), m.Konfera)) temata_a_spol = list(filter(ne_clanek_ne_konfera, hlavni_problemy)) @@ -415,6 +413,11 @@ def vysledkovka_cisla(cislo, context=None): je_nejake_ostatni = len(hlavni_problemy) - len(temata_a_spol) > 0 + setrizeni_resitele_slovnik = {} + setrizeni_resitele = m.Resitel.objects.filter(id__in=setrizeni_resitele_id).select_related('osoba') + for r in setrizeni_resitele: + setrizeni_resitele_slovnik[r.id] = r + for ar_id in setrizeni_resitele_id: # získáme seznam bodů za problémy pro daného řešitele body_problemy = [] @@ -428,7 +431,7 @@ def vysledkovka_cisla(cislo, context=None): # vytáhneme informace pro daného řešitele radek = RadekVysledkovkyCisla( poradi[i], # pořadí - m.Resitel.objects.get(id=ar_id), # řešitel (z id) + setrizeni_resitele_slovnik[ar_id], # řešitel (z id) body_problemy, # seznam bodů za hlavní problémy čísla cislobody[ar_id], # body za číslo setrizeni_resitele_body[i], # body za ročník (spočítané výše s pořadím)