|
|
|
from django.views.generic import ListView, DetailView
|
|
|
|
from django.views.generic.base import TemplateView
|
|
|
|
|
|
|
|
from dataclasses import dataclass
|
|
|
|
import datetime
|
|
|
|
|
|
|
|
import seminar.models as m
|
|
|
|
from seminar.utils import aktivniResitele, resi_v_rocniku
|
|
|
|
|
|
|
|
# Co chceme?
|
|
|
|
# - "Tabulku" aktuální řešitelé x zveřejněné problémy, v buňkách počet řešení
|
|
|
|
# - TabulkaOdevzdanychReseniView
|
|
|
|
# - Detail konkrétního problému a řešitele -- přehled všech řešení odevzdaných k tomuto problému
|
|
|
|
# - ReseniProblemuView
|
|
|
|
# - Detail konkrétního řešení -- všechny soubory, datum, ...
|
|
|
|
# - DetailReseniView
|
|
|
|
#
|
|
|
|
# Taky se může hodit:
|
|
|
|
# - Tabulka všech řešitelů x všech problémů?
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class SouhrnReseni:
|
|
|
|
"""Dataclass reprezentující data o odevzdaných řešeních pro zobrazení v tabulce."""
|
|
|
|
pocet_reseni : int
|
|
|
|
posledni_odevzdani : datetime.datetime
|
|
|
|
body : float
|
|
|
|
|
|
|
|
|
|
|
|
class TabulkaOdevzdanychReseniView(TemplateView):
|
|
|
|
template_name = 'TODO'
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
# 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,
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
nejnovejsi = None
|
|
|
|
pocet_bodu = None
|
|
|
|
ctx['radky'][resitel].append(
|
|
|
|
SouhrnReseni(
|
|
|
|
pocet_reseni=pocet_reseni,
|
|
|
|
posledni_odevzdani=nejnovejsi,
|
|
|
|
body=pocet_bodu,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
return ctx
|
|
|
|
|
|
|
|
class ReseniProblemuView(ListView):
|
|
|
|
model = m.Reseni
|
|
|
|
template_name = 'TODO'
|
|
|
|
|
|
|
|
def get_queryset(self):
|
|
|
|
qs = super().get_queryset()
|
|
|
|
resitel_id = self.kwargs['resitel']
|
|
|
|
if resitel_id is None:
|
|
|
|
raise ValueError("Nemám řešitele!")
|
|
|
|
problem_id = self.kwargs['problem']
|
|
|
|
if problem_id is None:
|
|
|
|
raise ValueError("Nemám problém! (To je problém!)")
|
|
|
|
|
|
|
|
resitel = m.Resitel.objects.get(id=resitel_id)
|
|
|
|
problem = m.Resitel.objects.get(id=problem_id)
|
|
|
|
qs = qs.filter(
|
|
|
|
problem__in=[problem],
|
|
|
|
resitele__in=[resitel],
|
|
|
|
)
|
|
|
|
return qs
|
|
|
|
|
|
|
|
# Kontext automaticky?
|
|
|
|
|
|
|
|
class DetailReseniView(DetailView):
|
|
|
|
model = m.Reseni
|
|
|
|
template_name = 'TODO'
|
|
|
|
# To je všechno? Najde se to podle pk...
|
|
|
|
|
|
|
|
# Přehled všech řešení kvůli debugování
|
|
|
|
|
|
|
|
class SeznamReseniView(ListView):
|
|
|
|
model = m.Reseni
|
|
|
|
template_name = 'TODO'
|
|
|
|
|
|
|
|
class SeznamAktualnichReseniView(SeznamReseniView):
|
|
|
|
def get_queryset(self):
|
|
|
|
qs = super().get_queryset()
|
|
|
|
akt_rocnik = m.Nastaveni.get_solo().aktualni_rocnik # .get_solo() vrátí tu jedinou instanci, asi...
|
|
|
|
resitele = resi_v_rocniku(akt_rocnik)
|
|
|
|
qs = qs.filter(resitele__in=resitele) # Doufám, že tohle najde řešení, která maji alespoň jednoho řešitele řešícího v aktuálním ročníku
|
|
|
|
return qs
|