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) | 	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): | 	def __str__(self): | ||||||
| 		return "{}, {}, {}".format(self.problem, self.reseni, self.body) | 		return "{}, {}, {}".format(self.problem, self.reseni, self.body) | ||||||
|  |  | ||||||
|  | @ -269,7 +269,7 @@ def sloupec_s_poradim(seznam_s_body): | ||||||
| 	for index in range(0, len(seznam_s_body)): | 	for index in range(0, len(seznam_s_body)): | ||||||
| 		# pokud je pořadí větší než číslo řádku, tak jsme vypsali větší rozsah a chceme | 		# pokud je pořadí větší než číslo řádku, tak jsme vypsali větší rozsah a chceme | ||||||
| 		# vypsat už jen prázdné místo, než dojdeme na správný řádek | 		# vypsat už jen prázdné místo, než dojdeme na správný řádek | ||||||
| 		if (index+1) < aktualni_poradi: | 		if (index + 1) < aktualni_poradi: | ||||||
| 			sloupec_s_poradim.append("") | 			sloupec_s_poradim.append("") | ||||||
| 			continue | 			continue | ||||||
| 		velikost_skupiny = 0 | 		velikost_skupiny = 0 | ||||||
|  | @ -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 | # 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): | 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  | 	# sečteme body za daný problém přes všechna řešení daného problému  | ||||||
| 	# od daného řešitele | 	# 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) | 				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: | 	for r in reseni_resitele: | ||||||
| 		soucet += r.body | 		soucet += r.body | ||||||
| 
 | 
 | ||||||
| 	# a přičteme k tomu hodnocení všech podproblémů | 	# 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ů | 	# i přes jméno by to měla být množina jeho podproblémů | ||||||
| 		soucet += __soucet_resitele_problemu(p, resitel, soucet) | 		soucet += __soucet_resitele_problemu(p, resitel, soucet) | ||||||
| 	return 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 | # vrátí list všech problémů s body v daném čísle, které již nemají nadproblém | ||||||
| def hlavni_problemy_cisla(cislo): | 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] | 	reseni = [h.reseni for h in hodnoceni] | ||||||
| 	problemy = [h.problem for h in hodnoceni] | 	problemy = [h.problem for h in hodnoceni] | ||||||
|  | @ -333,14 +332,22 @@ def hlavni_problemy_cisla(cislo): | ||||||
| 	# zunikátnění | 	# zunikátnění | ||||||
| 	hlavni_problemy_set = set(hlavni_problemy) | 	hlavni_problemy_set = set(hlavni_problemy) | ||||||
| 	hlavni_problemy = list(hlavni_problemy_set) | 	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 | 	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 | # spočítá součet všech bodů řešitele za dané číslo | ||||||
| def body_resitele_v_cisle(resitel, cislo): | def body_resitele_v_cisle(resitel, cislo): | ||||||
| 	hlavni_problemy = hlavni_problemy_cisla(cislo) | 	hlavni_problemy = hlavni_problemy_cisla(cislo) | ||||||
|  | 	body_resitele = 0 | ||||||
| 	for h in hlavni_problemy: | 	for h in hlavni_problemy: | ||||||
| 		body_resitele = body_resitele + body_resitele_problemu_v_cisle(h, resitel, cislo) | 		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 | 	# 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): | def body_resitele_v_rocniku(resitel, rocnik, do_cisla=None): | ||||||
| 	# pokud do_cisla=None, tak do posledního čísla v ročníku | 	# pokud do_cisla=None, tak do posledního čísla v ročníku | ||||||
| 	# do_cisla je objekt Cislo | 	# 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 | 	body = 0 | ||||||
| 	for cislo in cisla: | 	for cislo in cisla: | ||||||
| 		if cislo.poradi == do_cisla.poradi: break | 		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.""" | 	počet bodů za konkrétní ročník do daného čísla a za dané číslo.""" | ||||||
| 
 | 
 | ||||||
| 	def __init__(self, resitel, cislo, rocnik): | 	def __init__(self, resitel, cislo, rocnik): | ||||||
| 		resitel_jmeno = resitel.osoba.jmeno | 		self.resitel = resitel | ||||||
| 		resitel_prijmeni = resitel.osoba.prijmeni |  | ||||||
| 		self.cislo = cislo | 		self.cislo = cislo | ||||||
| 		body_cislo = body_resitele_v_cisle(resitel, cislo) | 		self.body_cislo = body_resitele_v_cisle(resitel, cislo) | ||||||
| 		body = [] | 		self.body = [] | ||||||
| 		self.rocnik = rocnik | 		self.rocnik = rocnik | ||||||
| 		body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) | 		self.body_rocnik = body_resitele_v_rocniku(resitel, rocnik, cislo) | ||||||
| 		poradi = 0 | 		self.body_celkem_odjakziva = resitel.vsechny_body() | ||||||
|  | 		self.poradi = 0 | ||||||
| 
 | 
 | ||||||
| class CisloView(generic.DetailView): | class CisloView(generic.DetailView): | ||||||
| 	model = Cislo | 	model = Cislo | ||||||
|  | @ -488,8 +496,8 @@ class CisloView(generic.DetailView): | ||||||
| 		if queryset is None: | 		if queryset is None: | ||||||
| 			queryset = self.get_queryset() | 			queryset = self.get_queryset() | ||||||
| 		rocnik_arg = self.kwargs.get('rocnik') | 		rocnik_arg = self.kwargs.get('rocnik') | ||||||
| 		cislo_arg = self.kwargs.get('cislo') | 		poradi_arg = self.kwargs.get('cislo') | ||||||
| 		queryset = queryset.filter(rocnik__rocnik=rocnik_arg, cislo=cislo_arg) | 		queryset = queryset.filter(rocnik__rocnik=rocnik_arg, poradi=poradi_arg) | ||||||
| 
 | 
 | ||||||
| 		try: | 		try: | ||||||
| 			obj = queryset.get() | 			obj = queryset.get() | ||||||
|  | @ -509,17 +517,18 @@ class CisloView(generic.DetailView): | ||||||
| 		## TODO možná chytřeji vybírat aktivní řešitele | 		## TODO možná chytřeji vybírat aktivní řešitele | ||||||
| 		## chceme letos něco poslal | 		## chceme letos něco poslal | ||||||
| 		aktivni_resitele = Resitel.objects.filter( | 		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) | 				#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) | ||||||
| 		radky_vysledkovky = [] | 		radky_vysledkovky = [] | ||||||
| 		for ar in aktivni_resitele: | 		for ar in aktivni_resitele: | ||||||
| 			# získáme výsledky řešitele - součty přes číslo a ročník | 			# získáme výsledky řešitele - součty přes číslo a ročník | ||||||
| 			vr = VysledkyResitele(ar, cislo, cislo.rocnik) | 			vr = VysledkyResitele(ar, cislo, cislo.rocnik) | ||||||
| 			for hp in hlavni_problemy: | 			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) | 			radky_vysledkovky.append(vr) | ||||||
| 
 | 
 | ||||||
| 		## TODO: |  | ||||||
| 		# setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů | 		# setřídíme řádky výsledkovky/objekty VysledkyResitele podle bodů | ||||||
| 		radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True) | 		radky_vysledkovky.sort(key=lambda vr: vr.body_rocnik, reverse=True) | ||||||
| 
 | 
 | ||||||
|  | @ -534,10 +543,13 @@ class CisloView(generic.DetailView): | ||||||
| 			i = i + 1 | 			i = i + 1 | ||||||
| 
 | 
 | ||||||
| 		# vytahané informace předáváme do kontextu | 		# vytahané informace předáváme do kontextu | ||||||
|  | 		context['cislo'] = cislo | ||||||
| 		context['radky_vysledkovky'] = radky_vysledkovky	 | 		context['radky_vysledkovky'] = radky_vysledkovky	 | ||||||
| 		context['problemy'] = hlavni_problemy | 		context['problemy'] = hlavni_problemy | ||||||
| #		context['v_cisle_zadane'] = TODO | #		context['v_cisle_zadane'] = TODO | ||||||
| #		context['resene_problemy'] = resene_problemy | #		context['resene_problemy'] = resene_problemy | ||||||
|  | 		#XXX testovat | ||||||
|  | 		#XXX opravit to, že se nezobrazují body za jednotlivé úlohy | ||||||
| 
 | 
 | ||||||
| 		return context | 		return context | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Anet
						Anet