Merge branch 'data_migrations' of gimli.ms.mff.cuni.cz:/akce/mam/git/mamweb into data_migrations
This commit is contained in:
		
						commit
						93a49ea057
					
				
					 3 changed files with 41 additions and 50 deletions
				
			
		|  | @ -41,6 +41,8 @@ Make commands | |||
| 
 | ||||
| * `make schema` - generates graph of seminar and all schemas as PDF. Supercool! | ||||
| 
 | ||||
| * `make sync_prod_flatpages` - downloads current flat/static pages from production version | ||||
| 
 | ||||
| ./manage.py commands | ||||
| -------------------- | ||||
| 
 | ||||
|  | @ -56,6 +58,8 @@ Make commands | |||
| 
 | ||||
| * `./manage.py test` - run the tests. | ||||
| 
 | ||||
| * `./manage.py shell` - run commands, list elemements of database, check syntax | ||||
|   by importing files, etc. | ||||
| 
 | ||||
| Configurations | ||||
| -------------- | ||||
|  |  | |||
|  | @ -353,7 +353,7 @@ class Rocnik(SeminarModelBase): | |||
| 	 | ||||
| 	def verejna_cisla(self): | ||||
| 		vc = [c for c in self.cisla.all() if c.verejne()] | ||||
| 		vc.sort(key=lambda c: c.cislo) | ||||
| 		vc.sort(key=lambda c: c.poradi) | ||||
| 		return vc | ||||
| 
 | ||||
| 	def posledni_verejne_cislo(self): | ||||
|  | @ -362,7 +362,7 @@ class Rocnik(SeminarModelBase): | |||
| 
 | ||||
| 	def verejne_vysledkovky_cisla(self): | ||||
| 		vc = list(self.cisla.filter(verejna_vysledkovka=True)) | ||||
| 		vc.sort(key=lambda c: c.cislo) | ||||
| 		vc.sort(key=lambda c: c.poradi) | ||||
| 		return vc | ||||
| 
 | ||||
| 	def posledni_zverejnena_vysledkovka_cislo(self): | ||||
|  | @ -387,7 +387,7 @@ class Rocnik(SeminarModelBase): | |||
| 
 | ||||
| def cislo_pdf_filename(self, filename): | ||||
| 	rocnik = str(self.rocnik.rocnik) | ||||
| 	return os.path.join('cislo', 'pdf', rocnik, '{}-{}.pdf'.format(rocnik, self.cislo)) | ||||
| 	return os.path.join('cislo', 'pdf', rocnik, '{}-{}.pdf'.format(rocnik, self.poradi)) | ||||
| 
 | ||||
| @reversion.register(ignore_duplicates=True) | ||||
| class Cislo(SeminarModelBase): | ||||
|  | @ -396,7 +396,7 @@ class Cislo(SeminarModelBase): | |||
| 		db_table = 'seminar_cisla' | ||||
| 		verbose_name = 'Číslo' | ||||
| 		verbose_name_plural = 'Čísla' | ||||
| 		ordering = ['-rocnik__rocnik', '-cislo'] | ||||
| 		ordering = ['-rocnik__rocnik', '-poradi'] | ||||
| 
 | ||||
| 	# Interní ID | ||||
| 	id = models.AutoField(primary_key = True) | ||||
|  | @ -404,7 +404,7 @@ class Cislo(SeminarModelBase): | |||
| 	rocnik = models.ForeignKey(Rocnik, verbose_name='ročník', related_name='cisla', | ||||
| 		db_index=True,on_delete=models.PROTECT) | ||||
| 
 | ||||
| 	cislo = models.CharField('název čísla', max_length=32, db_index=True, | ||||
| 	poradi = models.CharField('název čísla', max_length=32, db_index=True, | ||||
| 		help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určuje pořadí v ročníku!') | ||||
| 
 | ||||
| 	datum_vydani = models.DateField('datum vydání', blank=True, null=True, | ||||
|  | @ -437,20 +437,20 @@ class Cislo(SeminarModelBase): | |||
| 	# CisloNode | ||||
| 
 | ||||
| 	def kod(self): | ||||
| 		return '%s.%s' % (self.rocnik.rocnik, self.cislo) | ||||
| 		return '%s.%s' % (self.rocnik.rocnik, self.poradi) | ||||
| 	kod.short_description = 'Kód čísla' | ||||
| 
 | ||||
| 	def __str__(self): | ||||
| 		# Potenciální DB HOG, pokud by se ročník necachoval | ||||
| 		r = Rocnik.cached_rocnik(self.rocnik_id) | ||||
| 		return '{}.{}'.format(r.rocnik, self.cislo) | ||||
| 		return '{}.{}'.format(r.rocnik, self.poradi) | ||||
| 
 | ||||
| 	def verejne(self): | ||||
| 		return self.verejne_db | ||||
| 	verejne.boolean = True | ||||
| 
 | ||||
| 	def verejne_url(self): | ||||
| 		return reverse('seminar_cislo', kwargs={'rocnik': self.rocnik.rocnik, 'cislo': self.cislo}) | ||||
| 		return reverse('seminar_cislo', kwargs={'rocnik': self.rocnik.rocnik, 'cislo': self.poradi}) | ||||
| 
 | ||||
| 	def nasledujici(self): | ||||
| 		"Vrací None, pokud je toto poslední" | ||||
|  | @ -607,7 +607,7 @@ class Problem(SeminarModelBase,PolymorphicModel): | |||
| 
 | ||||
| 	# Problém má podproblémy | ||||
| 	nadproblem = models.ForeignKey('self', verbose_name='nadřazený problém', | ||||
| 		related_name='nadproblem_%(class)s', null=True, blank=True, | ||||
| 		related_name='podproblem', null=True, blank=True, | ||||
| 		on_delete=models.SET_NULL) | ||||
| 
 | ||||
| 	STAV_NAVRH = 'navrh' | ||||
|  | @ -772,7 +772,7 @@ class Uloha(Problem): | |||
| 
 | ||||
| 	def kod_v_rocniku(self): | ||||
| 		if self.stav == 'zadany': | ||||
| 			name="{}.u{}".format(self.cislo_zadani.cislo,self.kod) | ||||
| 			name="{}.u{}".format(self.cislo_zadani.poradi,self.kod) | ||||
| 			if self.nadproblem: | ||||
| 				return self.nadproblem.kod_v_rocniku()+name | ||||
| 			return name | ||||
|  | @ -1198,7 +1198,7 @@ class CisloNode(TreeNode): | |||
| 		on_delete = models.PROTECT, # Pokud chci mazat číslo, musím si Node pořešit ručně | ||||
| 		verbose_name = "číslo") | ||||
| 	def __str__(self): | ||||
| 		return 'CisloNode: '+str(self.cislo) | ||||
| 		return 'CisloNode: '+str(self.poradi) | ||||
| 
 | ||||
| class MezicisloNode(TreeNode): | ||||
| 	class Meta: | ||||
|  | @ -1319,7 +1319,7 @@ class TextNode(TreeNode): | |||
| # | ||||
| #	def __str__(self): | ||||
| #		return "%s: %sb (%s)".format(self.resitel.plne_jmeno(), self.body,  | ||||
| #		str(self.cislo)) | ||||
| #		str(self.poradi)) | ||||
| #		# NOTE: DB zatez pri vypisu (ale nepouzivany) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1369,7 +1369,7 @@ class TextNode(TreeNode): | |||
| # | ||||
| #	def __str__(self): | ||||
| #		# NOTE: DB HOG (ale nepouzivany) | ||||
| #		return "%s: %sb / %sb (do %s)" % (self.resitel.plne_jmeno(), self.body, self.body_celkem, str(self.cislo)) | ||||
| #		return "%s: %sb / %sb (do %s)" % (self.resitel.plne_jmeno(), self.body, self.body_celkem, str(self.poradi)) | ||||
| ##mozna potreba upravit | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -281,16 +281,18 @@ def sloupec_s_poradim(vysledky): | |||
| 	return poradi_l | ||||
| 
 | ||||
| # 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, 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  | ||||
| 	# od daného řešitele | ||||
| 	reseni_resitele = problem.hodnoceni_set.filter(reseni_resitele__contains=resitel) | ||||
| 	reseni_resitele = problem.hodnoceni_set.filter(reseni_resitele__contains=resitel,  | ||||
| 				cislo_body=cislo) | ||||
| 	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:  | ||||
| 	# i přes jméno by to měla být množina jeho podproblémů | ||||
| 		soucet += __soucet_resitele_problemu(p, resitel, soucet) | ||||
|  | @ -298,7 +300,8 @@ def __soucet_resitele_problemu(problem, resitel, soucet): | |||
| 
 | ||||
| # spočítá součet všech bodů ze všech podproblémů daného problému daného řešitele | ||||
| def body_resitele_problemu_v_cisle(problem, resitel, cislo): | ||||
| 	return __soucet_resitele_problemu(problem, resitel, 0) | ||||
| 	# probably FIXED: nezohledňuje číslo, do kterého se body počítají | ||||
| 	return __soucet_resitele_problemu(problem, resitel, cislo, 0) | ||||
| 
 | ||||
| # vrátí list všech problémů s body v daném čísle, které již nemají nadproblém | ||||
| def hlavni_problemy_cisla(cislo): | ||||
|  | @ -335,15 +338,15 @@ def body_resitele_v_cisle(resitel, cislo): | |||
| 	return body_resitele | ||||
| 
 | ||||
| # spočítá součet všech bodů řešitele za daný rok (nebo jen do daného čísla včetně) | ||||
| def body_resitele_v_rocniku(resitel, rocnik_node, 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 | ||||
| 	# do_cisla je objekt Cislo | ||||
| 	cislo_node = rocnik_node.firstChild | ||||
| 	cisla = rocnik.cisla # funkce vrátí pole objektů Cislo už lexikograficky setřízené, viz models | ||||
| 	body = 0 | ||||
| 	while not (cislo_node == None or cislo_node.cislo == do_cisla.CisloNode.next): | ||||
| 	for cislo in cisla: | ||||
| 		if cislo.poradi == do_cisla.poradi: break | ||||
| 		# druhá část zaručuje, že máme výsledky do daného čísla včetně | ||||
| 		body = body + body_resitele_v_cisle(resitel, cislo_node.cislo) | ||||
| 		cislo_node = cislo_node.next | ||||
| 		body = body + body_resitele_v_cisle(resitel, cislo) | ||||
| 	return body | ||||
| 
 | ||||
| #def vysledkovka_rocniku(rocnik, jen_verejne=True): | ||||
|  | @ -361,7 +364,7 @@ def body_resitele_v_rocniku(resitel, rocnik_node, do_cisla=None): | |||
| #		return None | ||||
| # | ||||
| #	#vybere vsechny vysledky z posledniho (verejneho) cisla a setridi sestupne dle bodu | ||||
| #	vysledky = list(cisla_v_rocniku.filter(cislo = cisla_v_rocniku[0].cislo).order_by('-body', 'resitel__prijmeni', 'resitel__jmeno').select_related('resitel')) | ||||
| #	vysledky = list(cisla_v_rocniku.filter(cislo = cisla_v_rocniku[0].poradi).order_by('-body', 'resitel__prijmeni', 'resitel__jmeno').select_related('resitel')) | ||||
| # | ||||
| #	class Vysledkovka: | ||||
| #		def __init__(self): | ||||
|  | @ -377,7 +380,7 @@ def body_resitele_v_rocniku(resitel, rocnik_node, do_cisla=None): | |||
| #		v.poradi = poradi | ||||
| #		v.resitel.rocnik = v.resitel.rocnik(rocnik) | ||||
| # | ||||
| #		verejne_vysl_odjakziva = VysledkyKCisluOdjakziva.objects.filter(cislo__rocnik=rocnik, cislo=cisla_v_rocniku[0].cislo) | ||||
| #		verejne_vysl_odjakziva = VysledkyKCisluOdjakziva.objects.filter(cislo__rocnik=rocnik, cislo=cisla_v_rocniku[0].poradi) | ||||
| #		if jen_verejne: | ||||
| #			verejne_vysl_odjakziva = verejne_vysl_odjakziva.filter(cislo__verejna_vysledkovka=True) | ||||
| # | ||||
|  | @ -459,11 +462,14 @@ class VysledkyResitele(object): | |||
| 		resitel_jmeno = resitel.osoba.jmeno | ||||
| 		resitel_prijmeni = resitel.osoba.prijmeni | ||||
| 		body = {} | ||||
| 		body_cislo = 0 | ||||
| 		body_rocnik = 0 | ||||
| 
 | ||||
| 	def body_za_cislo(self): | ||||
| 		return sum(body.values()) | ||||
| 
 | ||||
| 	def body_za_rocnik(self): | ||||
| 		return body_rocnik | ||||
| 
 | ||||
| class CisloView(generic.DetailView): | ||||
| 	model = Cislo | ||||
| 	template_name = 'seminar/archiv/cislo.html' | ||||
|  | @ -498,37 +504,18 @@ class CisloView(generic.DetailView): | |||
| 				#.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 jednotlivé hlavní problémy | ||||
| 			vr = VysledkyResitele(ar) | ||||
| 			for h in hlavni_problemy:  | ||||
| 				body = body_resitele_problemu_v_cisle(h, ar, cislo) | ||||
| #				vr.body[h.kod_v_rocniku] = body | ||||
| 				vr.body_cislo = vr.body_cislo + body  | ||||
| 			# ukládání součtu bodů za všechny hlavní problémy => součet bodů za číslo  | ||||
| 			vr.body_cislo = body_resitele_v_cisle(ar, cislo) | ||||
| 			# výpočet bodů za ročník do daného čísla (aby fungovalo i pro starší čísla) | ||||
| 			vr.body_rocnik = body_resitele_v_rocniku(ar, cislo.rocnik, cislo) | ||||
| 			radky_vysledkovky.append(vr) | ||||
| 
 | ||||
| 		## TODO: spočítat počet bodů řešitele v daném ročníku a seřadit je podle toho | ||||
| 		## TODO: seřadit řešitele podle bodů v daném ročníku | ||||
| 		## řazení viz fce výše - pochopit a případně přepsat | ||||
| 		## počet bodů udělat ve fce body_resitele_v_rocniku | ||||
| 		 | ||||
| 
 | ||||
| #		vysledky = VysledkyKCisluZaRocnik.objects.filter(cislo = context['cislo']).\ | ||||
| #			order_by('-body', 'resitel__prijmeni', 'resitel__jmeno') | ||||
| #		reseni = Reseni.objects.filter(cislo_body = context['cislo']).select_related("resitel") | ||||
| 
 | ||||
| 		# typy úloh, které se mají zobrazovat u čísla, tj. těch, které byly  | ||||
| 		# v čísle skutečně zadány | ||||
| #		typy_skutecne_zadanych = [Problem.TYP_ULOHA, Problem.TYP_SERIAL, Problem.TYP_ORG_CLANEK] | ||||
| #		v_cisle_zadane = Problem.objects.filter(cislo_zadani=context['cislo']).filter(typ__in=typy_skutecne_zadanych).order_by('kod') | ||||
| 
 | ||||
| #		resene_problemy = Problem.objects.filter(cislo_reseni=context['cislo']).filter(typ__in=typy_skutecne_zadanych).order_by('cislo_zadani__cislo', 'kod') | ||||
| # | ||||
| #		poradi_typu = { | ||||
| #			Problem.TYP_ULOHA: 1, | ||||
| 
 | ||||
| #			Problem.TYP_SERIAL: 2, | ||||
| #			Problem.TYP_ORG_CLANEK: 3, | ||||
| #			Problem.TYP_TEMA: 4, | ||||
| #			Problem.TYP_RES_CLANEK: 5 | ||||
| #		} | ||||
| #		problemy = sorted(set(r.problem for r in reseni), key=lambda x:(poradi_typu[x.typ], x.kod_v_rocniku())) | ||||
| #		#setridi problemy podle typu a poradi zadani | ||||
| #		problem_index = {} | ||||
|  | @ -975,7 +962,7 @@ def texDownloadView(request, rocnik, cislo): | |||
| 				"body": p.body, | ||||
| 				"zadani": p.text_zadani, | ||||
| 				"reseni": p.text_reseni, | ||||
| 				"cislo_zadani": p.cislo_zadani.cislo, | ||||
| 				"cislo_zadani": p.cislo_zadani.poradi, | ||||
| 			} for p in resene | ||||
| 		], | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue