From aa4b8da2abea0a5a11b16bb46f47317cbbd91d96 Mon Sep 17 00:00:00 2001 From: Anet Date: Thu, 9 Jan 2020 00:45:20 +0100 Subject: [PATCH] =?UTF-8?q?views=20|=20+-=20funk=C4=8Dn=C3=AD=20v=C3=BDsle?= =?UTF-8?q?dkovka=20se=20sn=C3=AD=C5=BEen=C3=BDm=20po=C4=8Dtem=20dotaz?= =?UTF-8?q?=C5=AF=20do=20datab=C3=A1ze?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- seminar/models.py | 3 ++- seminar/views.py | 52 +++++++++++++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/seminar/models.py b/seminar/models.py index 691c04af..d1bdd08c 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -913,7 +913,8 @@ class Hodnoceni(SeminarModelBase): 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): return "{}, {}, {}".format(self.problem, self.reseni, self.body) diff --git a/seminar/views.py b/seminar/views.py index 35e2bb6b..ba11c9b4 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -269,7 +269,7 @@ def sloupec_s_poradim(seznam_s_body): for index in range(0, len(seznam_s_body)): # pokud je pořadí větší než číslo řádku, tak jsme vypsali větší rozsah a chceme # vypsat už jen prázdné místo, než dojdeme na správný řádek - if (index+1) < aktualni_poradi: + if (index + 1) < aktualni_poradi: sloupec_s_poradim.append("") continue velikost_skupiny = 0 @@ -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 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 # 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) + # 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: soucet += r.body # 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ů soucet += __soucet_resitele_problemu(p, resitel, 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 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] problemy = [h.problem for h in hodnoceni] @@ -333,14 +332,22 @@ def hlavni_problemy_cisla(cislo): # 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.sort(key=lambda k: k.kod_v_rocniku()) # setřídit podle t1, t2, c3, ... 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 def body_resitele_v_cisle(resitel, cislo): hlavni_problemy = hlavni_problemy_cisla(cislo) + body_resitele = 0 for h in hlavni_problemy: 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 @@ -352,7 +359,8 @@ def body_resitele_v_cisle(resitel, cislo): def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): # pokud do_cisla=None, tak do posledního čísla v ročníku # 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 for cislo in cisla: 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.""" def __init__(self, resitel, cislo, rocnik): - resitel_jmeno = resitel.osoba.jmeno - resitel_prijmeni = resitel.osoba.prijmeni + self.resitel = resitel self.cislo = cislo - body_cislo = body_resitele_v_cisle(resitel, cislo) - body = [] + self.body_cislo = body_resitele_v_cisle(resitel, cislo) + self.body = [] self.rocnik = rocnik - body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) - poradi = 0 + self.body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) + self.body_celkem_odjakziva = resitel.vsechny_body() + self.poradi = 0 class CisloView(generic.DetailView): model = Cislo @@ -488,8 +496,8 @@ class CisloView(generic.DetailView): if queryset is None: queryset = self.get_queryset() rocnik_arg = self.kwargs.get('rocnik') - cislo_arg = self.kwargs.get('cislo') - queryset = queryset.filter(rocnik__rocnik=rocnik_arg, cislo=cislo_arg) + poradi_arg = self.kwargs.get('cislo') + queryset = queryset.filter(rocnik__rocnik=rocnik_arg, poradi=poradi_arg) try: obj = queryset.get() @@ -509,17 +517,18 @@ class CisloView(generic.DetailView): ## TODO možná chytřeji vybírat aktivní řešitele ## chceme letos něco poslal 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) radky_vysledkovky = [] for ar in aktivni_resitele: # získáme výsledky řešitele - součty přes číslo a ročník vr = VysledkyResitele(ar, cislo, cislo.rocnik) 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) - ## TODO: # setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True) @@ -534,10 +543,13 @@ class CisloView(generic.DetailView): i = i + 1 # vytahané informace předáváme do kontextu + context['cislo'] = cislo context['radky_vysledkovky'] = radky_vysledkovky context['problemy'] = hlavni_problemy # context['v_cisle_zadane'] = TODO # context['resene_problemy'] = resene_problemy + #XXX testovat + #XXX opravit to, že se nezobrazují body za jednotlivé úlohy return context