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.
This commit is contained in:
		
							parent
							
								
									4cfe76bb3a
								
							
						
					
					
						commit
						5fae78f3c7
					
				
					 2 changed files with 47 additions and 42 deletions
				
			
		|  | @ -9,11 +9,15 @@ | |||
| 		<th> {{ p }} </th> | ||||
| 		{% endfor %} | ||||
| 	</tr> | ||||
| 	{% for resitel, vysledky in radky %} | ||||
| 	{% for resitel,hodnoty in radky%} | ||||
| 	<tr> | ||||
| 		<td> {{ resitel } </td> | ||||
| 		{% for vysl in vysledky %} | ||||
| 		<td> {{ vysl.pocet_reseni }} řešení, dohromady za {{ vysl.body }}, nejnovější z {{ vysl.posledni_odevzdani }} </td> | ||||
| 		<td> {{ resitel }} </td> | ||||
| 		{% for hodn in hodnoty %} | ||||
| 			<td> | ||||
| 			{% if hodn %} | ||||
| 			{{ hodn.pocet_reseni }} řešení<br>{{ hodn.body }} bodů<br>{{ hodn.posledni_odevzdani }} | ||||
| 			{% endif %} | ||||
| 			</td> | ||||
| 		{% endfor %} | ||||
| 	</tr> | ||||
| 	{% endfor %} | ||||
|  |  | |||
|  | @ -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 = 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 | ||||
| 		 | ||||
| 		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, | ||||
| 								) | ||||
| 							] | ||||
| 						) | ||||
| 		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): | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Pavel "LEdoian" Turinsky
						Pavel "LEdoian" Turinsky