You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

114 lines
3.6 KiB

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 = 'seminar/odevzdavatko/tabulka.html'
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 = 'seminar/odevzdavatko/seznam.html'
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.Problem.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 = 'seminar/odevzdavatko/detail.html'
# 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 = 'seminar/odevzdavatko/seznam.html'
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) # FIXME: Najde řešení i ze starých ročníků, která odevzdal alespoň jeden aktuální řešitel
return qs