diff --git a/seminar/templates/seminar/odevzdavatko/tabulka.html b/seminar/templates/seminar/odevzdavatko/tabulka.html
index 893efa6d..ac628be6 100644
--- a/seminar/templates/seminar/odevzdavatko/tabulka.html
+++ b/seminar/templates/seminar/odevzdavatko/tabulka.html
@@ -9,11 +9,15 @@
{{ p }} |
{% endfor %}
- {% for resitel, vysledky in radky %}
+ {% for resitel,hodnoty in radky%}
- {{ resitel } |
- {% for vysl in vysledky %}
- {{ vysl.pocet_reseni }} řešení, dohromady za {{ vysl.body }}, nejnovější z {{ vysl.posledni_odevzdani }} |
+ {{ resitel }} |
+ {% for hodn in hodnoty %}
+
+ {% if hodn %}
+ {{ hodn.pocet_reseni }} řešení {{ hodn.body }} bodů {{ hodn.posledni_odevzdani }}
+ {% endif %}
+ |
{% endfor %}
{% endfor %}
diff --git a/seminar/views/odevzdavatko.py b/seminar/views/odevzdavatko.py
index 3f715bee..318b7bae 100644
--- a/seminar/views/odevzdavatko.py
+++ b/seminar/views/odevzdavatko.py
@@ -26,49 +26,50 @@ class SouhrnReseni:
body : float
-class TabulkaOdevzdanychReseniView(TemplateView):
+class TabulkaOdevzdanychReseniView(ListView):
template_name = 'seminar/odevzdavatko/tabulka.html'
+ model = m.Hodnoceni
+ akt_rocnik = m.Nastaveni.get_solo().aktualni_rocnik # .get_solo() vrátí tu jedinou instanci, asi...
+ resitele = resi_v_rocniku(akt_rocnik)
+ # NOTE: Protože řešení odkazuje přímo na Problém a QuerySet na Hodnocení je nepolymorfní, musíme porovnávat taky s nepolymorfními Problémy.
+ zadane_problemy = m.Problem.objects.filter(stav=m.Problem.STAV_ZADANY).non_polymorphic()
+
+ def get_queryset(self):
+ qs = super().get_queryset()
+ qs = qs.filter(problem__in=self.zadane_problemy).select_related('reseni', 'problem').prefetch_related('reseni__resitele__osoba')
+ return qs
def get_context_data(self, *args, **kwargs):
- akt_rocnik = m.Nastaveni.get_solo().aktualni_rocnik # .get_solo() vrátí tu jedinou instanci, asi...
- resitele = resi_v_rocniku(akt_rocnik)
- zadane_problemy = m.Problem.objects.filter(stav=m.Problem.STAV_ZADANY)
-
- ctx = dict()
- ctx['problemy'] = zadane_problemy
- ctx['resitele'] = resitele
+ ctx = super().get_context_data(*args, **kwargs)
+ ctx['problemy'] = self.zadane_problemy
+ ctx['resitele'] = self.resitele
+ tabulka = dict()
+
+ def pridej_reseni(problem, resitel, body, cas):
+ if problem not in tabulka:
+ tabulka[problem] = dict()
+ if resitel not in tabulka[problem]:
+ tabulka[problem][resitel] = SouhrnReseni(pocet_reseni=1, posledni_odevzdani=cas, body=body)
+ else:
+ tabulka[problem][resitel].posledni_odevzdani = max(tabulka[problem][resitel].posledni_odevzdani, cas)
+ tabulka[problem][resitel].body = max(tabulka[problem][resitel].body, body)
+ tabulka[problem][resitel].pocet_reseni += 1
- # Zkonstruujeme jednotlivé řádky
- # Řádky budou indexované řešiteli a budou obsahovat SouhrnyReseni
- # TODO: Tohle se asi nějak dá urychlit / zpřehlednit...
- ctx['radky'] = dict()
- for resitel in resitele:
- ctx['radky'][resitel] = []
- for problem in zadane_problemy:
- reseni_k_tomuto_problemu = m.Reseni.objects.filter(
- resitele__in=[resitel], # Snad funguje i takhle
- hodnoceni__problem__in=[problem], # ditto
- ).order_by('-cas_doruceni')
- pocet_reseni = reseni_k_tomuto_problemu.count()
- if pocet_reseni > 0:
- nejnovejsi = reseni_k_tomuto_problemu.first().cas_doruceni
- pocet_bodu = max(
- [h.body for h in m.Hodnoceni.objects.filter(
- reseni__in=reseni_k_tomuto_problemu,
- problem=problem,
- )
- ]
- )
+ for hodnoceni in self.get_queryset():
+ for resitel in hodnoceni.reseni.resitele.all():
+ pridej_reseni(hodnoceni.problem, resitel, hodnoceni.body, hodnoceni.reseni.cas_doruceni)
+
+ hodnoty = []
+ for resitel in self.resitele:
+ resiteluv_radek = []
+ for problem in self.zadane_problemy:
+ if problem in tabulka and resitel in tabulka[problem]:
+ resiteluv_radek.append(tabulka[problem][resitel])
else:
- nejnovejsi = None
- pocet_bodu = None
- ctx['radky'][resitel].append(
- SouhrnReseni(
- pocet_reseni=pocet_reseni,
- posledni_odevzdani=nejnovejsi,
- body=pocet_bodu,
- )
- )
+ resiteluv_radek.append(None)
+ hodnoty.append(resiteluv_radek)
+ ctx['radky'] = list(zip(self.resitele, hodnoty))
+
return ctx
class ReseniProblemuView(ListView):