Browse Source

Přepsána tabulka

Teď se ptá databáze jen málokrát (zdaleka ne jednou; TODO) a zbytek se
zpracovává v Pythonu.

Asi by to pořád šlo zlepšit pomocí agregací, ale whatever.
export_seznamu_prednasek
Pavel "LEdoian" Turinsky 4 years ago
parent
commit
5fae78f3c7
  1. 12
      seminar/templates/seminar/odevzdavatko/tabulka.html
  2. 77
      seminar/views/odevzdavatko.py

12
seminar/templates/seminar/odevzdavatko/tabulka.html

@ -9,11 +9,15 @@
<th> {{ p }} </th> <th> {{ p }} </th>
{% endfor %} {% endfor %}
</tr> </tr>
{% for resitel, vysledky in radky %} {% for resitel,hodnoty in radky%}
<tr> <tr>
<td> {{ resitel } </td> <td> {{ resitel }} </td>
{% for vysl in vysledky %} {% for hodn in hodnoty %}
<td> {{ vysl.pocet_reseni }} řešení, dohromady za {{ vysl.body }}, nejnovější z {{ vysl.posledni_odevzdani }} </td> <td>
{% if hodn %}
{{ hodn.pocet_reseni }} řešení<br>{{ hodn.body }} bodů<br>{{ hodn.posledni_odevzdani }}
{% endif %}
</td>
{% endfor %} {% endfor %}
</tr> </tr>
{% endfor %} {% endfor %}

77
seminar/views/odevzdavatko.py

@ -26,49 +26,50 @@ class SouhrnReseni:
body : float body : float
class TabulkaOdevzdanychReseniView(TemplateView): class TabulkaOdevzdanychReseniView(ListView):
template_name = 'seminar/odevzdavatko/tabulka.html' 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): def get_context_data(self, *args, **kwargs):
akt_rocnik = m.Nastaveni.get_solo().aktualni_rocnik # .get_solo() vrátí tu jedinou instanci, asi... ctx = super().get_context_data(*args, **kwargs)
resitele = resi_v_rocniku(akt_rocnik) ctx['problemy'] = self.zadane_problemy
zadane_problemy = m.Problem.objects.filter(stav=m.Problem.STAV_ZADANY) ctx['resitele'] = self.resitele
tabulka = dict()
ctx = dict()
ctx['problemy'] = zadane_problemy def pridej_reseni(problem, resitel, body, cas):
ctx['resitele'] = resitele 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 for hodnoceni in self.get_queryset():
# Řádky budou indexované řešiteli a budou obsahovat SouhrnyReseni for resitel in hodnoceni.reseni.resitele.all():
# TODO: Tohle se asi nějak dá urychlit / zpřehlednit... pridej_reseni(hodnoceni.problem, resitel, hodnoceni.body, hodnoceni.reseni.cas_doruceni)
ctx['radky'] = dict()
for resitel in resitele: hodnoty = []
ctx['radky'][resitel] = [] for resitel in self.resitele:
for problem in zadane_problemy: resiteluv_radek = []
reseni_k_tomuto_problemu = m.Reseni.objects.filter( for problem in self.zadane_problemy:
resitele__in=[resitel], # Snad funguje i takhle if problem in tabulka and resitel in tabulka[problem]:
hodnoceni__problem__in=[problem], # ditto resiteluv_radek.append(tabulka[problem][resitel])
).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: else:
nejnovejsi = None resiteluv_radek.append(None)
pocet_bodu = None hodnoty.append(resiteluv_radek)
ctx['radky'][resitel].append( ctx['radky'] = list(zip(self.resitele, hodnoty))
SouhrnReseni(
pocet_reseni=pocet_reseni,
posledni_odevzdani=nejnovejsi,
body=pocet_bodu,
)
)
return ctx return ctx
class ReseniProblemuView(ListView): class ReseniProblemuView(ListView):

Loading…
Cancel
Save