views | +- funkční výsledkovka se sníženým počtem dotazů do databáze
This commit is contained in:
		
							parent
							
								
									f29f25ef21
								
							
						
					
					
						commit
						aa4b8da2ab
					
				
					 2 changed files with 34 additions and 21 deletions
				
			
		|  | @ -913,7 +913,8 @@ class Hodnoceni(SeminarModelBase): | |||
| 
 | ||||
| 	reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE) | ||||
| 
 | ||||
| 	problem = models.ForeignKey(Problem, verbose_name='problém', on_delete=models.PROTECT) | ||||
| 	problem = models.ForeignKey(Problem, verbose_name='problém',  | ||||
| 		related_name='hodnoceni', on_delete=models.PROTECT) | ||||
| 
 | ||||
| 	def __str__(self): | ||||
| 		return "{}, {}, {}".format(self.problem, self.reseni, self.body) | ||||
|  |  | |||
|  | @ -292,18 +292,17 @@ def sloupec_s_poradim(seznam_s_body): | |||
| 
 | ||||
| # spočítá součet bodů získaných daným řešitelem za zadaný problém a všechny jeho podproblémy | ||||
| def __soucet_resitele_problemu(problem, resitel, cislo, soucet): | ||||
| 	# FIXME: správně je nadproblem_(typ problemu), ale to by bylo potřeba nějak  | ||||
| 	# zjistit, jaký typ nodu to vlastně je a aplikovat to ve volání funkce | ||||
| 
 | ||||
| 	# sečteme body za daný problém přes všechna řešení daného problému  | ||||
| 	# od daného řešitele | ||||
| 	reseni_resitele = problem.hodnoceni_set.filter(reseni_resitele__contains=resitel,  | ||||
| 	reseni_resitele = problem.hodnoceni_set.filter(reseni__resitele=resitel,  | ||||
| 				cislo_body=cislo) | ||||
| 	# XXX chyba na řádku výše - řešení může mít více řešitelů, asi chceme contains | ||||
| 	# nebo in | ||||
| 	for r in reseni_resitele: | ||||
| 		soucet += r.body | ||||
| 
 | ||||
| 	# a přičteme k tomu hodnocení všech podproblémů | ||||
| 	for p in problem.nadproblem_set:  | ||||
| 	for p in problem.podproblem.all():  | ||||
| 	# i přes jméno by to měla být množina jeho podproblémů | ||||
| 		soucet += __soucet_resitele_problemu(p, resitel, soucet) | ||||
| 	return soucet | ||||
|  | @ -315,7 +314,7 @@ def body_resitele_problemu_v_cisle(problem, resitel, cislo): | |||
| 
 | ||||
| # vrátí list všech problémů s body v daném čísle, které již nemají nadproblém | ||||
| def hlavni_problemy_cisla(cislo): | ||||
| 	hodnoceni = cislo.hodnoceni_set	# hodnocení, která se vážou k danému číslu | ||||
| 	hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all()	# hodnocení, která se vážou k danému číslu | ||||
| 	 | ||||
| 	reseni = [h.reseni for h in hodnoceni] | ||||
| 	problemy = [h.problem for h in hodnoceni] | ||||
|  | @ -333,14 +332,22 @@ def hlavni_problemy_cisla(cislo): | |||
| 	# zunikátnění | ||||
| 	hlavni_problemy_set = set(hlavni_problemy) | ||||
| 	hlavni_problemy = list(hlavni_problemy_set) | ||||
| 	hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku) # setřídit podle t1, t2, c3, ... | ||||
| 	hlavni_problemy.sort(key=lambda k: k.kod_v_rocniku()) # setřídit podle t1, t2, c3, ... | ||||
| 	 | ||||
| 	return hlavni_problemy | ||||
| 
 | ||||
| def body_resitele_odjakziva(resitel): | ||||
| 	body = 0 | ||||
| 	resitelova_hodnoceni = Hodnoceni.objects.select_related('body').all().filter(reseni_resitele=resitel) | ||||
| 	# TODO: v radku nahore chceme _in nebo _contains | ||||
| 	for hodnoceni in resitelova_hodnoceni: | ||||
| 		body = body + hodnoceni.body | ||||
| 	return body | ||||
| 
 | ||||
| # spočítá součet všech bodů řešitele za dané číslo | ||||
| def body_resitele_v_cisle(resitel, cislo): | ||||
| 	hlavni_problemy = hlavni_problemy_cisla(cislo) | ||||
| 	body_resitele = 0 | ||||
| 	for h in hlavni_problemy: | ||||
| 		body_resitele = body_resitele + body_resitele_problemu_v_cisle(h, resitel, cislo) | ||||
| 	# TODO: je rozdíl mezi odevzdanou úlohou za 0 a tím, když řešitel nic neodevzdal | ||||
|  | @ -352,7 +359,8 @@ def body_resitele_v_cisle(resitel, cislo): | |||
| def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): | ||||
| 	# pokud do_cisla=None, tak do posledního čísla v ročníku | ||||
| 	# do_cisla je objekt Cislo | ||||
| 	cisla = rocnik.cisla # funkce vrátí pole objektů Cislo už lexikograficky setřízené, viz models | ||||
| 	cisla = rocnik.cisla.all() # funkce vrátí pole objektů  | ||||
| 	# Cislo už lexikograficky setřízené, viz models | ||||
| 	body = 0 | ||||
| 	for cislo in cisla: | ||||
| 		if cislo.poradi == do_cisla.poradi: break | ||||
|  | @ -470,14 +478,14 @@ class VysledkyResitele(object): | |||
| 	počet bodů za konkrétní ročník do daného čísla a za dané číslo.""" | ||||
| 
 | ||||
| 	def __init__(self, resitel, cislo, rocnik): | ||||
| 		resitel_jmeno = resitel.osoba.jmeno | ||||
| 		resitel_prijmeni = resitel.osoba.prijmeni | ||||
| 		self.resitel = resitel | ||||
| 		self.cislo = cislo | ||||
| 		body_cislo = body_resitele_v_cisle(resitel, cislo) | ||||
| 		body = [] | ||||
| 		self.body_cislo = body_resitele_v_cisle(resitel, cislo) | ||||
| 		self.body = [] | ||||
| 		self.rocnik = rocnik | ||||
| 		body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) | ||||
| 		poradi = 0 | ||||
| 		self.body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) | ||||
| 		self.body_celkem_odjakziva = resitel.vsechny_body() | ||||
| 		self.poradi = 0 | ||||
| 
 | ||||
| class CisloView(generic.DetailView): | ||||
| 	model = Cislo | ||||
|  | @ -488,8 +496,8 @@ class CisloView(generic.DetailView): | |||
| 		if queryset is None: | ||||
| 			queryset = self.get_queryset() | ||||
| 		rocnik_arg = self.kwargs.get('rocnik') | ||||
| 		cislo_arg = self.kwargs.get('cislo') | ||||
| 		queryset = queryset.filter(rocnik__rocnik=rocnik_arg, cislo=cislo_arg) | ||||
| 		poradi_arg = self.kwargs.get('cislo') | ||||
| 		queryset = queryset.filter(rocnik__rocnik=rocnik_arg, poradi=poradi_arg) | ||||
| 
 | ||||
| 		try: | ||||
| 			obj = queryset.get() | ||||
|  | @ -509,17 +517,18 @@ class CisloView(generic.DetailView): | |||
| 		## TODO možná chytřeji vybírat aktivní řešitele | ||||
| 		## chceme letos něco poslal | ||||
| 		aktivni_resitele = Resitel.objects.filter( | ||||
| 				rok_maturity__gte=context['rocnik'].druhy_rok()) | ||||
| 				rok_maturity__gte=cislo.rocnik.druhy_rok()) | ||||
| 				# TODO: zkusit hodnoceni__rocnik... | ||||
| 				#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) | ||||
| 		radky_vysledkovky = [] | ||||
| 		for ar in aktivni_resitele: | ||||
| 			# získáme výsledky řešitele - součty přes číslo a ročník | ||||
| 			vr = VysledkyResitele(ar, cislo, cislo.rocnik) | ||||
| 			for hp in hlavni_problemy: | ||||
| 				vr.body.append(body_resitele_problemu_v_cisle(hp, resitel, cislo)) | ||||
| 				vr.body.append( | ||||
| 				body_resitele_problemu_v_cisle(hp, ar, cislo)) | ||||
| 			radky_vysledkovky.append(vr) | ||||
| 
 | ||||
| 		## TODO: | ||||
| 		# setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů | ||||
| 		radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True) | ||||
| 
 | ||||
|  | @ -534,10 +543,13 @@ class CisloView(generic.DetailView): | |||
| 			i = i + 1 | ||||
| 
 | ||||
| 		# vytahané informace předáváme do kontextu | ||||
| 		context['cislo'] = cislo | ||||
| 		context['radky_vysledkovky'] = radky_vysledkovky	 | ||||
| 		context['problemy'] = hlavni_problemy | ||||
| #		context['v_cisle_zadane'] = TODO | ||||
| #		context['resene_problemy'] = resene_problemy | ||||
| 		#XXX testovat | ||||
| 		#XXX opravit to, že se nezobrazují body za jednotlivé úlohy | ||||
| 
 | ||||
| 		return context | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Anet
						Anet