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> | 		<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 %} | ||||||
|  |  | ||||||
|  | @ -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() | ||||||
|  | 
 | ||||||
|  | 		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() | 		for hodnoceni in self.get_queryset(): | ||||||
| 		ctx['problemy'] = zadane_problemy | 			for resitel in hodnoceni.reseni.resitele.all(): | ||||||
| 		ctx['resitele'] = resitele | 				pridej_reseni(hodnoceni.problem, resitel, hodnoceni.body, hodnoceni.reseni.cas_doruceni) | ||||||
| 		 | 
 | ||||||
| 		# Zkonstruujeme jednotlivé řádky | 		hodnoty = [] | ||||||
| 		# Řádky budou indexované řešiteli a budou obsahovat SouhrnyReseni | 		for resitel in self.resitele: | ||||||
| 		# TODO: Tohle se asi nějak dá urychlit / zpřehlednit... | 			resiteluv_radek = [] | ||||||
| 		ctx['radky'] = dict() | 			for problem in self.zadane_problemy: | ||||||
| 		for resitel in resitele: | 				if problem in tabulka and resitel in tabulka[problem]: | ||||||
| 			ctx['radky'][resitel] = [] | 					resiteluv_radek.append(tabulka[problem][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: | 				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…
	
		Reference in a new issue
	
	 Pavel "LEdoian" Turinsky
						Pavel "LEdoian" Turinsky