From 3504d5788e9b03b073605d336fbcfbf08983a481 Mon Sep 17 00:00:00 2001 From: Tomas 'Jethro' Pokorny Date: Tue, 23 Feb 2021 23:48:20 +0100 Subject: [PATCH] vysledkovka | Optimalizace pristupu k DB --- seminar/views/views_all.py | 24 ++++++++++-------------- seminar/views/vysledkovka.py | 24 ++++++++++++++++++++---- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index d4a875fd..d7c7d041 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') @@ -644,29 +644,25 @@ class RocnikView(generic.DetailView): def get_object(self, queryset=None): if queryset is None: queryset = self.get_queryset() - rocnik_arg = self.kwargs.get('rocnik') - queryset = queryset.filter(rocnik=rocnik_arg) - try: - obj = queryset.get() - except queryset.model.DoesNotExist: - raise Http404(_("No %(verbose_name)s found matching the query") % - {'verbose_name': queryset.model._meta.verbose_name}) - return obj + return get_object_or_404(queryset,rocnik=self.kwargs.get('rocnik')) def get_context_data(self, **kwargs): + start = time.time() context = super(RocnikView, self).get_context_data(**kwargs) # vysledkovka = True zajistí vykreslení, # zkontrolovat, kdy se má a nemá vykreslovat context['vysledkovka'] = True - context['cisla_s_neverejnymi'] = cisla_rocniku(context["rocnik"], jen_verejne=False) + 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) context['cisla'] = cisla_rocniku(context["rocnik"]) context['radky_vysledkovky'] = vysledkovka_rocniku(context["rocnik"]) - context['radky_vysledkovky_s_neverejnymi'] = vysledkovka_rocniku( - context["rocnik"], jen_verejne=False) context['hlavni_problemy_v_rocniku'] = hlavni_problemy_rocniku(context["rocnik"]) - context['hlavni_problemy_v_rocniku_s_neverejnymi'] = hlavni_problemy_rocniku(context["rocnik"], jen_verejne=False) + end = time.time() + print("Kontext:", end-start) return context @@ -689,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') diff --git a/seminar/views/vysledkovka.py b/seminar/views/vysledkovka.py index dd8956b9..bbdb067f 100644 --- a/seminar/views/vysledkovka.py +++ b/seminar/views/vysledkovka.py @@ -1,6 +1,7 @@ import seminar.models as m from django.db.models import Q, Sum, Count from seminar.utils import aktivniResitele, resi_v_rocniku, cisla_rocniku, hlavni_problemy_rocniku, hlavni_problem, hlavni_problemy_cisla, problemy_cisla, podproblemy_v_cislu +import time ### Výsledky def sloupec_s_poradim(setrizene_body): @@ -126,15 +127,16 @@ class RadekVysledkovkyRocniku(object): def setrid_resitele_a_body(slov_resitel_body): setrizeni_resitele_id = [dvojice[0] for dvojice in slov_resitel_body] - setrizeni_resitele = [m.Resitel.objects.get(id=i) for i in setrizeni_resitele_id] setrizene_body = [dvojice[1] for dvojice in slov_resitel_body] - return setrizeni_resitele_id, setrizeni_resitele, setrizene_body + return setrizeni_resitele_id, setrizene_body def vysledkovka_rocniku(rocnik, jen_verejne=True): """ Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html" """ + start = time.time() + ## TODO možná chytřeji vybírat aktivní řešitele # aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají # u alespoň jedné hodnoty něco jiného než NULL @@ -150,7 +152,7 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): resitel_rocnikbody_sezn = secti_body_za_rocnik(rocnik, aktivni_resitele) # setřídíme řešitele podle počtu bodů a získáme seznam s body od nejvyšších po nenižší - setrizeni_resitele_id, setrizeni_resitele, setrizene_body = setrid_resitele_a_body(resitel_rocnikbody_sezn) + setrizeni_resitele_id, setrizene_body = setrid_resitele_a_body(resitel_rocnikbody_sezn) poradi = sloupec_s_poradim(setrizene_body) # získáme body odjakživa @@ -159,6 +161,10 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): # vytvoříme jednotlivé sloupce výsledkovky radky_vysledkovky = [] i = 0 + setrizeni_resitele_dict = {} # Tento slovnik se vyrab + for r in m.Resitel.objects.filter(id__in=setrizeni_resitele_id).select_related('osoba'): + setrizeni_resitele_dict[r.id] = r + for ar_id in setrizeni_resitele_id: # seznam počtu bodů daného řešitele pro jednotlivá čísla body_cisla_sezn = [] @@ -168,7 +174,7 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): # vytáhneme informace pro daného řešitele radek = RadekVysledkovkyRocniku( poradi[i], # pořadí - m.Resitel.objects.get(id=ar_id), # řešitel (z id) + setrizeni_resitele_dict[ar_id], # řešitel (z id) body_cisla_sezn, # seznam bodů za čísla setrizene_body[i], # body za ročník (spočítané výše s pořadím) resitel_odjakzivabody_slov[ar_id], # body odjakživa @@ -176,7 +182,11 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): radky_vysledkovky.append(radek) i += 1 + end = time.time() + print("Vysledkovka rocniku",end-start) + return radky_vysledkovky + class RadekVysledkovkyCisla(object): """Obsahuje věci, které se hodí vědět při konstruování výsledkovky. Umožňuje snazší práci v templatu (lepší, než seznam).""" @@ -225,6 +235,9 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): # TODO setřídit hlavní problémy čísla podle id, ať jsou ve stejném pořadí pokaždé # pro každý hlavní problém zavedeme slovník s body za daný hlavní problém # pro jednotlivé řešitele (slovník slovníků hlavních problémů) + + print("Scitam cislo",cislo) + if hlavni_problemy is None: hlavni_problemy = hlavni_problemy_cisla(cislo) @@ -257,6 +270,7 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): reseni_do_cisla = m.Reseni.objects.prefetch_related('problem', 'resitele', 'hodnoceni_set').filter(hodnoceni__cislo_body=cislo) + start = time.time() # projdeme všechna řešení do čísla a přičteme body každému řešiteli do celkových # bodů i do bodů za problém for reseni in reseni_do_cisla: @@ -280,6 +294,8 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): continue pricti_body(cislobody, resitel, body) pricti_body(nadproblem_slovnik, resitel, body) + end = time.time() + print("for cykly:", end-start) return hlavni_problemy_slovnik, cislobody