Browse Source

views | +- funkční výsledkovka se sníženým počtem dotazů do databáze

export_seznamu_prednasek
Anet 5 years ago
parent
commit
aa4b8da2ab
  1. 3
      seminar/models.py
  2. 50
      seminar/views.py

3
seminar/models.py

@ -913,7 +913,8 @@ class Hodnoceni(SeminarModelBase):
reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE) reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE)
problem = models.ForeignKey(Problem, verbose_name='problém', on_delete=models.PROTECT) problem = models.ForeignKey(Problem, verbose_name='problém',
related_name='hodnoceni', on_delete=models.PROTECT)
def __str__(self): def __str__(self):
return "{}, {}, {}".format(self.problem, self.reseni, self.body) return "{}, {}, {}".format(self.problem, self.reseni, self.body)

50
seminar/views.py

@ -292,18 +292,17 @@ def sloupec_s_poradim(seznam_s_body):
# spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy # spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy
def __soucet_resitele_problemu(problem, resitel, cislo, soucet): def __soucet_resitele_problemu(problem, resitel, cislo, soucet):
# FIXME: správně je nadproblem_(typ problemu), ale to by bylo potřeba nějak
# zjistit, jaký typ nodu to vlastně je a aplikovat to ve volání funkce
# sečteme body za daný problém přes všechna řešení daného problému # sečteme body za daný problém přes všechna řešení daného problému
# od daného řešitele # od daného řešitele
reseni_resitele = problem.hodnoceni_set.filter(reseni_resitele__contains=resitel, reseni_resitele = problem.hodnoceni_set.filter(reseni__resitele=resitel,
cislo_body=cislo) cislo_body=cislo)
# XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains
# nebo in
for r in reseni_resitele: for r in reseni_resitele:
soucet += r.body soucet += r.body
# a přičteme k tomu hodnocení všech podproblémů # a přičteme k tomu hodnocení všech podproblémů
for p in problem.nadproblem_set: for p in problem.podproblem.all():
# i přes jméno by to měla být množina jeho podproblémů # i přes jméno by to měla být množina jeho podproblémů
soucet += __soucet_resitele_problemu(p, resitel, soucet) soucet += __soucet_resitele_problemu(p, resitel, soucet)
return soucet return soucet
@ -315,7 +314,7 @@ def body_resitele_problemu_v_cisle(problem, resitel, cislo):
# vrátí list všech problémů s body v daném čísle, které již nemají nadproblém # vrátí list všech problémů s body v daném čísle, které již nemají nadproblém
def hlavni_problemy_cisla(cislo): def hlavni_problemy_cisla(cislo):
hodnoceni = cislo.hodnoceni_set # hodnocení, která se vážou k danému číslu hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all() # hodnocení, která se vážou k danému číslu
reseni = [h.reseni for h in hodnoceni] reseni = [h.reseni for h in hodnoceni]
problemy = [h.problem for h in hodnoceni] problemy = [h.problem for h in hodnoceni]
@ -333,14 +332,22 @@ def hlavni_problemy_cisla(cislo):
# zunikátnění # zunikátnění
hlavni_problemy_set = set(hlavni_problemy) hlavni_problemy_set = set(hlavni_problemy)
hlavni_problemy = list(hlavni_problemy_set) hlavni_problemy = list(hlavni_problemy_set)
hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku) # setřídit podle t1, t2, c3, ... hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku()) # setřídit podle t1, t2, c3, ...
return hlavni_problemy return hlavni_problemy
def body_resitele_odjakziva(resitel):
body = 0
resitelova_hodnoceni = Hodnoceni.objects.select_related('body').all().filter(reseni_resitele=resitel)
# TODO: v radku nahore chceme _in nebo _contains
for hodnoceni in resitelova_hodnoceni:
body = body + hodnoceni.body
return body
# spočítá součet všech bodů řešitele za dané číslo # spočítá součet všech bodů řešitele za dané číslo
def body_resitele_v_cisle(resitel, cislo): def body_resitele_v_cisle(resitel, cislo):
hlavni_problemy = hlavni_problemy_cisla(cislo) hlavni_problemy = hlavni_problemy_cisla(cislo)
body_resitele = 0
for h in hlavni_problemy: for h in hlavni_problemy:
body_resitele = body_resitele + body_resitele_problemu_v_cisle(h, resitel, cislo) body_resitele = body_resitele + body_resitele_problemu_v_cisle(h, resitel, cislo)
# TODO: je rozdíl mezi odevzdanou úlohou za 0 a tím, když řešitel nic neodevzdal # TODO: je rozdíl mezi odevzdanou úlohou za 0 a tím, když řešitel nic neodevzdal
@ -352,7 +359,8 @@ def body_resitele_v_cisle(resitel, cislo):
def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None):
# pokud do_cisla=None, tak do posledního čísla v ročníku # pokud do_cisla=None, tak do posledního čísla v ročníku
# do_cisla je objekt Cislo # do_cisla je objekt Cislo
cisla = rocnik.cisla # funkce vrátí pole objektů Cislo už lexikograficky setřízené, viz models cisla = rocnik.cisla.all() # funkce vrátí pole objektů
# Cislo už lexikograficky setřízené, viz models
body = 0 body = 0
for cislo in cisla: for cislo in cisla:
if cislo.poradi == do_cisla.poradi: break if cislo.poradi == do_cisla.poradi: break
@ -470,14 +478,14 @@ class VysledkyResitele(object):
počet bodů za konkrétní ročník do daného čísla a za dané číslo.""" počet bodů za konkrétní ročník do daného čísla a za dané číslo."""
def __init__(self, resitel, cislo, rocnik): def __init__(self, resitel, cislo, rocnik):
resitel_jmeno = resitel.osoba.jmeno self.resitel = resitel
resitel_prijmeni = resitel.osoba.prijmeni
self.cislo = cislo self.cislo = cislo
body_cislo = body_resitele_v_cisle(resitel, cislo) self.body_cislo = body_resitele_v_cisle(resitel, cislo)
body = [] self.body = []
self.rocnik = rocnik self.rocnik = rocnik
body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) self.body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo)
poradi = 0 self.body_celkem_odjakziva = resitel.vsechny_body()
self.poradi = 0
class CisloView(generic.DetailView): class CisloView(generic.DetailView):
model = Cislo model = Cislo
@ -488,8 +496,8 @@ class CisloView(generic.DetailView):
if queryset is None: if queryset is None:
queryset = self.get_queryset() queryset = self.get_queryset()
rocnik_arg = self.kwargs.get('rocnik') rocnik_arg = self.kwargs.get('rocnik')
cislo_arg = self.kwargs.get('cislo') poradi_arg = self.kwargs.get('cislo')
queryset = queryset.filter(rocnik__rocnik=rocnik_arg, cislo=cislo_arg) queryset = queryset.filter(rocnik__rocnik=rocnik_arg, poradi=poradi_arg)
try: try:
obj = queryset.get() obj = queryset.get()
@ -509,17 +517,18 @@ class CisloView(generic.DetailView):
## TODO možná chytřeji vybírat aktivní řešitele ## TODO možná chytřeji vybírat aktivní řešitele
## chceme letos něco poslal ## chceme letos něco poslal
aktivni_resitele = Resitel.objects.filter( aktivni_resitele = Resitel.objects.filter(
rok_maturity__gte=context['rocnik'].druhy_rok()) rok_maturity__gte=cislo.rocnik.druhy_rok())
# TODO: zkusit hodnoceni__rocnik...
#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) #.filter(hodnoceni_set__rocnik__eq=cislo_rocnik)
radky_vysledkovky = [] radky_vysledkovky = []
for ar in aktivni_resitele: for ar in aktivni_resitele:
# získáme výsledky řešitele - součty přes číslo a ročník # získáme výsledky řešitele - součty přes číslo a ročník
vr = VysledkyResitele(ar, cislo, cislo.rocnik) vr = VysledkyResitele(ar, cislo, cislo.rocnik)
for hp in hlavni_problemy: for hp in hlavni_problemy:
vr.body.append(body_resitele_problemu_v_cisle(hp, resitel, cislo)) vr.body.append(
body_resitele_problemu_v_cisle(hp, ar, cislo))
radky_vysledkovky.append(vr) radky_vysledkovky.append(vr)
## TODO:
# setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů # setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů
radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True) radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True)
@ -534,10 +543,13 @@ class CisloView(generic.DetailView):
i = i + 1 i = i + 1
# vytahané informace předáváme do kontextu # vytahané informace předáváme do kontextu
context['cislo'] = cislo
context['radky_vysledkovky'] = radky_vysledkovky context['radky_vysledkovky'] = radky_vysledkovky
context['problemy'] = hlavni_problemy context['problemy'] = hlavni_problemy
# context['v_cisle_zadane'] = TODO # context['v_cisle_zadane'] = TODO
# context['resene_problemy'] = resene_problemy # context['resene_problemy'] = resene_problemy
#XXX testovat
#XXX opravit to, že se nezobrazují body za jednotlivé úlohy
return context return context

Loading…
Cancel
Save