Předělání sousových views #57
					 159 changed files with 3463 additions and 883 deletions
				
			
		|  | @ -5,16 +5,16 @@ urlpatterns = [ | |||
| 	path( | ||||
| 		'aesop-export/mam-rocnik-<int:prvni_rok>.csv', | ||||
| 		views.ExportRocnikView.as_view(), | ||||
| 		name='seminar_export_rocnik' | ||||
| 		name='aesop_export_rocnik' | ||||
| 	), | ||||
| 	path( | ||||
| 		'aesop-export/mam-sous-<str:datum_zacatku>.csv', | ||||
| 		views.ExportSousView.as_view(), | ||||
| 		name='seminar_export_sous' | ||||
| 		name='aesop_export_sous' | ||||
| 	), | ||||
| 	path( | ||||
| 		'aesop-export/index.csv', | ||||
| 		views.ExportIndexView.as_view(), | ||||
| 		name='seminar_export_index' | ||||
| 		name='aesop_export_index' | ||||
| 	), | ||||
| ] | ||||
|  |  | |||
|  | @ -6,7 +6,8 @@ from django.views import generic | |||
| from django.utils.encoding import force_str | ||||
| 
 | ||||
| from .utils import default_ovvpfile | ||||
| from seminar.models import Rocnik, Soustredeni | ||||
| from soustredeni.models import Soustredeni | ||||
| from tvorba.models import Rocnik | ||||
| from vysledkovky import utils | ||||
| from tvorba.utils import aktivniResitele | ||||
| 
 | ||||
|  | @ -14,10 +15,10 @@ class ExportIndexView(generic.View): | |||
| 	def get(self, request): | ||||
| 		ls = [] | ||||
| 		for r in Rocnik.objects.filter(exportovat = True): | ||||
| 	    		url = reverse('seminar_export_rocnik', kwargs={'prvni_rok': r.prvni_rok}) | ||||
| 	    		url = reverse('aesop_export_rocnik', kwargs={'prvni_rok': r.prvni_rok}) | ||||
| 	    		ls.append(url.split('/')[-1]) | ||||
| 		for s in Soustredeni.objects.filter(exportovat = True): | ||||
| 			url = reverse('seminar_export_sous', kwargs={'datum_zacatku': s.datum_zacatku.isoformat()}) | ||||
| 			url = reverse('aesop_export_sous', kwargs={'datum_zacatku': s.datum_zacatku.isoformat()}) | ||||
| 			ls.append(url.split('/')[-1]) | ||||
| 
 | ||||
| 		return HttpResponse('\n'.join(ls) + '\n', content_type='text/plain; charset=utf-8') | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| from django.test import TestCase, tag | ||||
| from django.urls import reverse | ||||
| import seminar.models as m | ||||
| from personalni.models import Skola | ||||
| from personalni.utils import sync_skoly | ||||
| 
 | ||||
| @tag('stejny-model-na-produkci') | ||||
|  | @ -48,7 +48,7 @@ class OrgSkolyAutocompleteTestCase(TestCase): | |||
| 		"""Testuje, že pro každého orga je jeho škola ve výsledném QuerySetu""" | ||||
| 		for pfx, id in self.spravna_data: | ||||
| 			with self.subTest(prefix=pfx, spravne_id=id): | ||||
| 				spravna_skola = m.Skola.objects.get(id=id) | ||||
| 				spravna_skola = Skola.objects.get(id=id) | ||||
| 				# Zeptáme se view, co si myslí | ||||
| 				resp = self.client.get(reverse('autocomplete_skola')+'?q='+pfx).json() | ||||
| 				ids = [int(x['id']) for x in resp['results']] | ||||
|  |  | |||
|  | @ -17,5 +17,5 @@ urlpatterns = [ | |||
| 	# Ceka na autocomplete v3 | ||||
| 	# path('autocomplete/organizatori/', | ||||
| 	# org_member_required(views.OrganizatorAutocomplete.as_view()), | ||||
| 	# name='seminar_autocomplete_organizator') | ||||
| 	# name='autocomplete_organizator') | ||||
| ] | ||||
|  |  | |||
|  | @ -5,7 +5,9 @@ from dal import autocomplete | |||
| from django.shortcuts import get_object_or_404 | ||||
| from django.db.models import Q | ||||
| 
 | ||||
| import seminar.models as m | ||||
| from personalni.models import Skola, Resitel | ||||
| from tvorba.models import Problem | ||||
| from various.models import Nastaveni | ||||
| from .helpers import LoginRequiredAjaxMixin | ||||
| 
 | ||||
| # TODO filosofie - zkratky, jak v databázi, tak ve vyhledávání (SPŠE, GASOŠ, Kpt., soukr) | ||||
|  | @ -13,7 +15,7 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView): | |||
| 	""" View k :mod:`dal.autocomplete` pro vyhledávání škol hlavně při registraci. """ | ||||
| 	def get_queryset(self): | ||||
| 		# Don't forget to filter out results depending on the visitor ! | ||||
| 		qs = m.Skola.objects.all() | ||||
| 		qs = Skola.objects.all() | ||||
| 		if self.q: | ||||
| 			words = self.q.split(' ') #TODO re split podle bileho znaku | ||||
| 			partq = Q() | ||||
|  | @ -31,7 +33,7 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView): | |||
| class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetView): | ||||
| 	""" View k :mod:`dal.autocomplete` pro vyhledávání řešitelů především v odevzdávátku. """ | ||||
| 	def get_queryset(self): | ||||
| 		qs = m.Resitel.objects.all() | ||||
| 		qs = Resitel.objects.all() | ||||
| 		if self.q: | ||||
| 			parts = self.q.split() | ||||
| 			query = Q() | ||||
|  | @ -51,8 +53,8 @@ class PublicResitelAutocomplete(LoginRequiredAjaxMixin, autocomplete.Select2Quer | |||
| 		především v odevzdávátku. | ||||
| 	""" | ||||
| 	def get_queryset(self): | ||||
| 		letos = m.Nastaveni.get_solo().aktualni_rocnik | ||||
| 		qs = m.Resitel.objects.filter( | ||||
| 		letos = Nastaveni.get_solo().aktualni_rocnik | ||||
| 		qs = Resitel.objects.filter( | ||||
| 			rok_maturity__gte=letos.druhy_rok() | ||||
| 		).filter( | ||||
| 			prezdivka_resitele__isnull=False | ||||
|  | @ -70,7 +72,7 @@ class PublicResitelAutocomplete(LoginRequiredAjaxMixin, autocomplete.Select2Quer | |||
| class OdevzdatelnyProblemAutocomplete(autocomplete.Select2QuerySetView): | ||||
| 	""" View k :mod:`dal.autocomplete` pro vyhledávání problémů především v odevzdávátku. """ | ||||
| 	def get_queryset(self): | ||||
| 		qs = m.Problem.objects.filter(stav=m.Problem.STAV_ZADANY) | ||||
| 		qs = Problem.objects.filter(stav=Problem.STAV_ZADANY) | ||||
| 		if self.q: | ||||
| 			qs = qs.filter( | ||||
| 					Q(nazev__icontains=self.q)) | ||||
|  | @ -87,12 +89,12 @@ class ProblemAutocomplete(autocomplete.Select2QuerySetView): | |||
| 	""" View k :mod:`dal.autocomplete` pro vyhledávání problémů především v odevzdávátku. """ | ||||
| 	def get_queryset(self): | ||||
| 		# FIXME i starší úlohy | ||||
| 		nastaveni = get_object_or_404(m.Nastaveni) | ||||
| 		nastaveni = get_object_or_404(Nastaveni) | ||||
| 		rocnik = nastaveni.aktualni_rocnik | ||||
| 		temaQ = Q(Tema___rocnik = rocnik) | ||||
| 		ulohaQ = Q(Uloha___cislo_zadani__rocnik=rocnik) | ||||
| 		clanekQ = Q(Clanek___cislo__rocnik=rocnik) | ||||
| 		qs = m.Problem.objects.filter(temaQ | ulohaQ | clanekQ).order_by("-stav", "nazev") | ||||
| 		qs = Problem.objects.filter(temaQ | ulohaQ | clanekQ).order_by("-stav", "nazev") | ||||
| 		if self.q: | ||||
| 			qs = qs.filter( | ||||
| 					Q(nazev__icontains=self.q)) | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import seminar.models as m | ||||
| import personalni.models as m | ||||
| from django.core import serializers as ser | ||||
| from django.http import HttpResponse | ||||
| def exportSkolView(request): | ||||
|  |  | |||
|  | @ -73,7 +73,7 @@ | |||
| 			"sort_order": 3, | ||||
| 			"title": "Aktuální<br/> ročník", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_aktualni_zadani", | ||||
| 			"url": "tvorba_aktualni_zadani", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -121,7 +121,7 @@ | |||
| 			"sort_order": 5, | ||||
| 			"title": "Archiv", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_archiv_rocniky", | ||||
| 			"url": "tvorba_archiv_rocniky", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -289,7 +289,7 @@ | |||
| 			"sort_order": 43, | ||||
| 			"title": "Výsledková listina", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_aktualni_vysledky", | ||||
| 			"url": "tvorba_aktualni_vysledky", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -361,7 +361,7 @@ | |||
| 			"sort_order": 20, | ||||
| 			"title": "Proběhlo", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_seznam_soustredeni", | ||||
| 			"url": "soustredeni_seznam", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -409,7 +409,7 @@ | |||
| 			"sort_order": 23, | ||||
| 			"title": "Osobní údaje", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_resitel_edit", | ||||
| 			"url": "personalni_resitel_edit", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -439,7 +439,7 @@ | |||
| 			"sort_order": 36, | ||||
| 			"title": "Nahrát řešení", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_nahraj_reseni", | ||||
| 			"url": "odevzdavatko_nahraj_reseni", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -463,7 +463,7 @@ | |||
| 			"sort_order": 35, | ||||
| 			"title": "Témata", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_archiv_temata", | ||||
| 			"url": "tvorba_archiv_temata", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -589,7 +589,7 @@ | |||
| 			"sort_order": 15, | ||||
| 			"title": "Aktuální číslo", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_aktualni_zadani", | ||||
| 			"url": "tvorba_aktualni_zadani", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -613,7 +613,7 @@ | |||
| 			"sort_order": 24, | ||||
| 			"title": "Čísla", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_archiv_rocniky", | ||||
| 			"url": "tvorba_archiv_rocniky", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -721,7 +721,7 @@ | |||
| 			"sort_order": 36, | ||||
| 			"title": "Vložit řešení", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_vloz_reseni", | ||||
| 			"url": "odevzdavatko_vloz_reseni", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -804,7 +804,7 @@ | |||
| 			"sort_order": 37, | ||||
| 			"title": "Moje řešení", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_resitel_odevzdana_reseni", | ||||
| 			"url": "odevzdavatko_resitel_odevzdana_reseni", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -828,7 +828,7 @@ | |||
| 			"sort_order": 33, | ||||
| 			"title": "Aktuální ročník", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_aktualni_rocnik", | ||||
| 			"url": "tvorba_aktualni_rocnik", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -900,7 +900,7 @@ | |||
| 			"sort_order": 46, | ||||
| 			"title": "Ročník {{rocnik.rocnik}}", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_rocnik rocnik.rocnik", | ||||
| 			"url": "tvorba_rocnik rocnik.rocnik", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -924,7 +924,7 @@ | |||
| 			"sort_order": 47, | ||||
| 			"title": "Číslo {{ cislo.rocnik.rocnik }}.{{ cislo.poradi }}", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_cislo cislo.rocnik.rocnik cislo.poradi", | ||||
| 			"url": "tvorba_cislo cislo.rocnik.rocnik cislo.poradi", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -1007,7 +1007,18 @@ | |||
| 			"access_guest": false, | ||||
| 			"access_loggedin": false, | ||||
| 			"access_perm_type": 1, | ||||
| 			"access_permissions": [], | ||||
| 			"access_permissions": [ | ||||
| 				[ | ||||
| 					"org", | ||||
| 					"auth", | ||||
| 					"user" | ||||
| 				], | ||||
| 				[ | ||||
| 					"resitel", | ||||
| 					"auth", | ||||
| 					"user" | ||||
| 				] | ||||
| 			], | ||||
| 			"access_restricted": true, | ||||
| 			"alias": null, | ||||
| 			"description": "", | ||||
|  | @ -1050,7 +1061,7 @@ | |||
| 			"sort_order": 52, | ||||
| 			"title": "Nahrát řešení k nadproblému {{nadproblem_id}}", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_nahraj_reseni nadproblem_id", | ||||
| 			"url": "odevzdavatko_nahraj_reseni nadproblem_id", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  | @ -1086,7 +1097,7 @@ | |||
| 			"access_loggedin": false, | ||||
| 			"access_perm_type": 1, | ||||
| 			"access_permissions": [], | ||||
| 			"access_restricted": true, | ||||
| 			"access_restricted": false, | ||||
| 			"alias": null, | ||||
| 			"description": "", | ||||
| 			"hidden": false, | ||||
|  | @ -1098,7 +1109,7 @@ | |||
| 			"sort_order": 54, | ||||
| 			"title": "Export do abstraktů sousu {{ soustredeni.id }}", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_soustredeni_abstrakty soustredeni.id", | ||||
| 			"url": "soustredeni_abstrakty soustredeni.id", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
|  |  | |||
|  | @ -216,57 +216,57 @@ | |||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "add_cislo", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "cislo" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "change_cislo", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "cislo" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "delete_cislo", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "cislo" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "view_cislo", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "cislo" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "add_clanek", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "clanek" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "change_clanek", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "clanek" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "delete_clanek", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "clanek" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "view_clanek", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "clanek" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "add_deadline", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "deadline" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "change_deadline", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "deadline" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "view_deadline", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "deadline" | ||||
| 	}, | ||||
| 	{ | ||||
|  | @ -371,22 +371,22 @@ | |||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "add_pohadka", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "pohadka" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "change_pohadka", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "pohadka" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "delete_pohadka", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "pohadka" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "view_pohadka", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "pohadka" | ||||
| 	}, | ||||
| 	{ | ||||
|  | @ -411,22 +411,22 @@ | |||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "add_problem", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "problem" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "change_problem", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "problem" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "delete_problem", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "problem" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "view_problem", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "problem" | ||||
| 	}, | ||||
| 	{ | ||||
|  | @ -441,22 +441,22 @@ | |||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "add_rocnik", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "rocnik" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "change_rocnik", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "rocnik" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "delete_rocnik", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "rocnik" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "view_rocnik", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "rocnik" | ||||
| 	}, | ||||
| 	{ | ||||
|  | @ -541,42 +541,42 @@ | |||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "add_tema", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "tema" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "change_tema", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "tema" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "delete_tema", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "tema" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "view_tema", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "tema" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "add_uloha", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "uloha" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "change_uloha", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "uloha" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "delete_uloha", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "uloha" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "view_uloha", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "tvorba", | ||||
| 		"ct_model": "uloha" | ||||
| 	}, | ||||
| 	{ | ||||
|  |  | |||
|  | @ -10,11 +10,9 @@ věci jako chybové hlášky a vzhled M&M stránek (menu, patička, atd.). Aktu | |||
| i veškeré csv. | ||||
| 
 | ||||
| Další jsou pak jednotlivé aplikace (pokud něco hledáte, tak zřejmě chcete najít | ||||
| tu aplikaci, která tomu odpovídá, respektive se k ní dostat přes url), za | ||||
| zmínku stojí seminar, kde jsou takové ty věci, co zbyly. Plus jsou tam aktuálně | ||||
| téměř všechny modely, protože je těžké je přesunout jinam. | ||||
| tu aplikaci, která tomu odpovídá, respektive se k ní dostat přes url). | ||||
| 
 | ||||
| **TLDR: Nevšímejte si složky data/ a souborů přímo v kořenové složce.** | ||||
| **TLDR: Nevšímejte si složek data/ seminar/ a souborů přímo v kořenové složce.** | ||||
| Kromě věcí potřebných ke gitu, :doc:`ke spuštění <vyvoj>` a fukci djanga, | ||||
| dalších drobností, lokální databáze a již zmíněných aplikací jsou tu ``data``, | ||||
| kde je takový ten obsah webu, co by se měl dát snadno měnit (tudíž musí být v | ||||
|  | @ -22,6 +20,9 @@ databázi), tj. statické stránky, menu a obrázky v pozadí menu. Ten je třeb | |||
| měnit hlavně na produkci a sekundárně tady (může to dělat i newebař a nechcete | ||||
| přepsat jeho práci). Vše, co nejsou aplikace je popsáno :doc:`tady <dalsi_soubory>`. | ||||
| 
 | ||||
| Ještě je tu aplikace ``seminar/``, kde bylo původně skoro všechno, a tak nám | ||||
| tam zbývá spoustu historických migrací (čehož se jen tak nezbavíme). | ||||
| 
 | ||||
| Základy djanga | ||||
| -------------- | ||||
| 
 | ||||
|  |  | |||
|  | @ -116,7 +116,7 @@ Aktuálně: Jakýsi coding style zhruba existuje, není popsaný, šíří se li | |||
| - Nesmí být striktně vynucovaný | ||||
| - Musel by být hodně nastavitelný | ||||
|     - Nechceme mít kód plný `#NOQA: WTF42` | ||||
| - Nejspíš vždycky bude mít false positives (`tvorba.utils.roman_numerals`) i false negatives (`seminar.models.tvorba.Cislo.posli_cislo_mailem`) | ||||
| - Nejspíš vždycky bude mít false positives (`tvorba.utils.roman_numerals`) i false negatives (`tvorba.models.Cislo.posli_cislo_mailem`) | ||||
|     - Možná dobrý sluha, ale určitě špatný pán (also: špatná zkušenost ☺) | ||||
| - __Důsledek:__ Hrozí, že těch falešných varování bude moc, čímž to ztratí smysl úplně | ||||
|     - Potenciálně by šlo aplikovat jen lokálně na změny? | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ from django.template import RequestContext | |||
| from datetime import datetime | ||||
| 
 | ||||
| from galerie.models import Obrazek, Galerie | ||||
| from seminar.models import Soustredeni | ||||
| from soustredeni.models import Soustredeni | ||||
| from galerie.forms import KomentarForm, NewGalerieForm | ||||
| 
 | ||||
| def zobrazit(galerie, request): | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ set -exuo pipefail | |||
| . make/lib.sh | ||||
| 
 | ||||
| scp vue_frontend/webpack-stats.json "$GIMLI_LOGIN:$TESTWEB/vue_frontend/" | ||||
| rsync -ave ssh seminar/static/seminar/vue "$GIMLI_LOGIN:$TESTWEB/seminar/static/seminar/" | ||||
| rsync -ave ssh treenode/static/treenode/vue "$GIMLI_LOGIN:$TESTWEB/treenode/static/treenode/" | ||||
| ssh "$GIMLI_LOGIN" " | ||||
| 	set -euxo pipefail | ||||
| 	cd $TESTWEB | ||||
|  |  | |||
|  | @ -5,5 +5,4 @@ set -exuo pipefail | |||
| 
 | ||||
| ensure_web_installed | ||||
| 
 | ||||
| ./manage.py graph_models seminar | dot -Tpdf > schema_seminar.pdf | ||||
| ./manage.py graph_models -a -g | dot -Tpdf > schema_all.pdf | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ def get_app_list(self, request, app_label=None): | |||
| 
 | ||||
| 	app_dict = self._build_app_dict(request, label=app_label) | ||||
| 	aplikace_nahore = [ | ||||
| 		'seminar', | ||||
| 		'tvorba', | ||||
| 		'personalni', | ||||
| 		'novinky', | ||||
| 		'korektury', | ||||
|  | @ -57,7 +57,7 @@ def get_app_list(self, request, app_label=None): | |||
| 
 | ||||
| 	# Sort the models alphabetically within each app. | ||||
| 	for app in app_list: | ||||
| 		app['models'].sort(key=lambda x: locale.strxfrm('žž' + x['name'].lower()) if (x['name'].endswith("(Node)")) else locale.strxfrm(x['name'].lower())) | ||||
| 		app['models'].sort(key=lambda x: locale.strxfrm(x['name'].lower())) | ||||
| 
 | ||||
| 	return app_list | ||||
| 
 | ||||
|  |  | |||
|  | @ -279,11 +279,11 @@ LOGGING = { | |||
| 				'filters': ['Http404AsInfo'], | ||||
| 				}, | ||||
| 
 | ||||
| 			'seminar.prihlaska.form':{ | ||||
| 			'personalni.prihlaska.form':{ | ||||
| 		'handlers': ['console','registration_logfile'], | ||||
| 		'level': 'INFO' | ||||
| 		}, | ||||
| 			'seminar.prihlaska.problem':{ | ||||
| 			'personalni.prihlaska.problem':{ | ||||
| 		'handlers': ['console','mail_registration','registration_error_log'], | ||||
| 		'level': 'INFO' | ||||
| 		}, | ||||
|  |  | |||
|  | @ -19,10 +19,10 @@ div.kontejner {/* Ne container, aby se to netlouklo s bootstrapem. */ | |||
| 		margin-top: var(--login-bar-height); | ||||
| 	} | ||||
| 
 | ||||
| 	div.kontent-wrapper { | ||||
| 	& div.kontent-wrapper { | ||||
| 		padding-bottom: var(--footer-height); | ||||
| 
 | ||||
| 		div.kontent { | ||||
| 		& div.kontent { | ||||
| 			padding: 15px 30px; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -67,16 +67,16 @@ div.kontejner {/* Ne container, aby se to netlouklo s bootstrapem. */ | |||
| 	background-size: 100%; | ||||
| 	top: 58px; | ||||
| 
 | ||||
| 	img.logo { | ||||
| 	& img.logo { | ||||
| 		width: 100%; | ||||
| 		filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); | ||||
| 	} | ||||
| 
 | ||||
| 	img.logo-mobile { | ||||
| 	& img.logo-mobile { | ||||
| 		display: none; | ||||
| 	} | ||||
| 
 | ||||
| 	.no-mobile { | ||||
| 	& .no-mobile { | ||||
| 		background-size: contain; | ||||
| 	} | ||||
| } | ||||
|  | @ -94,12 +94,12 @@ div.kontejner {/* Ne container, aby se to netlouklo s bootstrapem. */ | |||
| 	filter: drop-shadow(5px 0px 5px rgba(0, 0, 0, 0.4)); | ||||
| 	padding-top: 3.5%; | ||||
| 
 | ||||
| 	p.license { | ||||
| 	& p.license { | ||||
| 		text-align: center; | ||||
| 		font-weight: 400; | ||||
| 		bottom: 0; | ||||
| 
 | ||||
| 		a { | ||||
| 		& a { | ||||
| 			color: #333; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -139,21 +139,21 @@ div.login-bar { | |||
| 	padding-left: 5px; | ||||
| 	padding-right: 5px; | ||||
| 
 | ||||
| 	div { | ||||
| 	& div { | ||||
| 		display: inline; | ||||
| 	} | ||||
| 
 | ||||
| 	a.LOGIN-ref-admin { | ||||
| 	& a.LOGIN-ref-admin { | ||||
| 		display: inline; | ||||
| 		color: var(--barva-pozadi); | ||||
| 	} | ||||
| 
 | ||||
| 	.LOGIN_napis-webarum { | ||||
| 	& .LOGIN_napis-webarum { | ||||
| 		display: inline; | ||||
| 		color: var(--barva-pozadi); | ||||
| 		float: right; | ||||
| 
 | ||||
| 		a { | ||||
| 		& a { | ||||
| 			color: var(--svetla-oranzova); | ||||
| 			text-decoration: underline; | ||||
| 		} | ||||
|  | @ -176,7 +176,7 @@ div.login-bar { | |||
| 	#header { | ||||
| 		background-size: 100%; | ||||
| 
 | ||||
| 		img.logo { | ||||
| 		& img.logo { | ||||
| 			width: 100%; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -202,11 +202,11 @@ div.login-bar { | |||
| 		top: 0; | ||||
| 		background-image: none; | ||||
| 
 | ||||
| 		img.logo { | ||||
| 		& img.logo { | ||||
| 			display: none; | ||||
| 		} | ||||
| 
 | ||||
| 		img.logo-mobile { | ||||
| 		& img.logo-mobile { | ||||
| 			display: block; | ||||
| 			top: 0; | ||||
| 			left: 0; | ||||
|  | @ -215,7 +215,7 @@ div.login-bar { | |||
| 			margin-bottom: 3px; | ||||
| 		} | ||||
| 
 | ||||
| 		.no-mobile{ | ||||
| 		& .no-mobile{ | ||||
| 			display: none; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -241,13 +241,13 @@ ul.menu { | |||
| 
 | ||||
| 	font-variant: small-caps; | ||||
| 
 | ||||
| 	a { | ||||
| 	& a { | ||||
| 		text-decoration: none; | ||||
| 		font-weight: bold; | ||||
| 		font-size: 105%; | ||||
| 	} | ||||
| 
 | ||||
| 	li { | ||||
| 	& li { | ||||
| 		margin: 0; | ||||
| 		display: inline-block; | ||||
| 		width: 16.666667%; | ||||
|  | @ -256,7 +256,7 @@ ul.menu { | |||
| 		font-size: 140%; | ||||
| 		font-weight: 400; | ||||
| 
 | ||||
| 		>a:hover, >a:active { | ||||
| 		&>a:hover, &>a:active { | ||||
| 			color: black; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -265,7 +265,7 @@ ul.menu { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	ul.submenu { | ||||
| 	& ul.submenu { | ||||
| 
 | ||||
| 		background-color: var(--hlavni-oranzova); | ||||
| 		margin-top: 10px; /* mezera mezi hlavním menu a submenu */ | ||||
|  | @ -277,24 +277,24 @@ ul.menu { | |||
| 		z-index: 50; | ||||
| 		font-weight: 400; | ||||
| 
 | ||||
| 		li { | ||||
| 		& li { | ||||
| 			width: auto; | ||||
| 			padding: 0 20px 0 20px; | ||||
| 			display: inline-block; | ||||
| 
 | ||||
| 			>a { | ||||
| 			&>a { | ||||
| 				color: var(--svetla-oranzova); | ||||
| 				text-decoration: none; | ||||
| 				text-shadow: none; | ||||
| 
 | ||||
| 				:hover { | ||||
| 				&:hover { | ||||
| 					color: black; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	ul.submenu li.active>a, .parentactive ul li:first-child>a { | ||||
| 	& ul.submenu li.active>a, & .parentactive ul li:first-child>a { | ||||
| 		color: black; | ||||
| 	} | ||||
| } | ||||
|  | @ -304,7 +304,7 @@ ul.menu { | |||
| 		font-size: 90%; | ||||
| 		margin-top: -7px; | ||||
| 
 | ||||
| 		li { | ||||
| 		& li { | ||||
| 			margin-top: 10px; /* posunutí textu hlavního menu níže */ | ||||
| 		} | ||||
| 	} | ||||
|  | @ -312,7 +312,7 @@ ul.menu { | |||
| 	ul.submenu { | ||||
| 		margin-top: 8px; /* mezera mezi hlavním menu a submenu */ | ||||
| 
 | ||||
| 		li { | ||||
| 		& li { | ||||
| 			margin-top: 0; /* aby se spolu s textem hlavního menu neposunoval níže i text submenu */ | ||||
| 		} | ||||
| 	} | ||||
|  | @ -323,7 +323,7 @@ ul.menu { | |||
| 		font-size: 80%; | ||||
| 		margin-top: -2px; | ||||
| 
 | ||||
| 		li { | ||||
| 		& li { | ||||
| 			margin-top: 10px; /* posunutí textu hlavního menu níže */ | ||||
| 		} | ||||
| 	} | ||||
|  | @ -331,7 +331,7 @@ ul.menu { | |||
| 	ul.submenu { | ||||
| 		margin-top: 8px; /* mezera mezi hlavním menu a submenu */ | ||||
| 
 | ||||
| 		li { | ||||
| 		& li { | ||||
| 			margin-top: 0; /* aby se spolu s textem hlavního menu neposunoval níže i text submenu */ | ||||
| 		} | ||||
| 	} | ||||
|  | @ -354,20 +354,20 @@ ul.menu { | |||
| 		padding-bottom: 3px; | ||||
| 		padding-left: 12px; | ||||
| 
 | ||||
| 		a { | ||||
| 		& a { | ||||
| 			&:active, &:hover, &:focus { | ||||
| 				text-decoration: none; | ||||
| 				color: black; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		ul { | ||||
| 		& ul { | ||||
| 			list-style-type: none; | ||||
| 			font-size: 90%; | ||||
| 			color: black; /*černé šipky submenu*/ | ||||
| 
 | ||||
| 			li { | ||||
| 				> a { | ||||
| 			& li { | ||||
| 				&>a { | ||||
| 					color: black; | ||||
| 				} | ||||
| 
 | ||||
|  | @ -377,7 +377,7 @@ ul.menu { | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		br { | ||||
| 		& br { | ||||
| 			display: none; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -459,13 +459,13 @@ body.suprodweb { &:before, &:after { background: red; } } | |||
| 		display: block; | ||||
| 	} | ||||
| 
 | ||||
| 	h1 { text-align: center; } | ||||
| 	& h1 { text-align: center; } | ||||
| 
 | ||||
| 	.TITULNI_STRANA_zjistit_vic{ | ||||
| 	& .TITULNI_STRANA_zjistit_vic{ | ||||
| 		text-align: center; | ||||
| 		margin-bottom: 30px; | ||||
| 
 | ||||
| 		hr { | ||||
| 		& hr { | ||||
| 			display: none; | ||||
| 
 | ||||
| 			@media(max-width: 800px){ | ||||
|  | @ -474,15 +474,15 @@ body.suprodweb { &:before, &:after { background: red; } } | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	.TITULNI_STRANA_graf { | ||||
| 	& .TITULNI_STRANA_graf { | ||||
| 		@media(max-width: 800px) { | ||||
| 			padding-top: 40px; | ||||
| 		} | ||||
| 
 | ||||
| 		.TITULNI_STRANA_graf-svg { | ||||
| 		& .TITULNI_STRANA_graf-svg { | ||||
| 			display: flex; | ||||
| 
 | ||||
| 			#svg-graf { | ||||
| 			& #svg-graf { | ||||
| 				width: 100%; | ||||
| 				height: auto; | ||||
| 				margin: 30px; | ||||
|  | @ -496,7 +496,7 @@ body.suprodweb { &:before, &:after { background: red; } } | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	.TITULNI_STRANA_obsah { | ||||
| 	& .TITULNI_STRANA_obsah { | ||||
| 		width: 66%; | ||||
| 
 | ||||
| 		@media(max-width: 800px){ | ||||
|  | @ -504,7 +504,7 @@ body.suprodweb { &:before, &:after { background: red; } } | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	.TITULNI_STRANA_vitej_titulka, .TITULNI_STRANA_temata_titulka { | ||||
| 	& .TITULNI_STRANA_vitej_titulka, & .TITULNI_STRANA_temata_titulka { | ||||
| 		width: 49%; | ||||
| 		padding: 10px; | ||||
| 		display: table-cell; | ||||
|  | @ -515,7 +515,7 @@ body.suprodweb { &:before, &:after { background: red; } } | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	.TITULNI_STRANA_novinky { | ||||
| 	& .TITULNI_STRANA_novinky { | ||||
| 		width: 33%; | ||||
| 		padding: 10px; | ||||
| 
 | ||||
|  | @ -540,11 +540,11 @@ div.odpocet { | |||
| .stranka_aktualni_zadani { | ||||
| 	text-align: center; | ||||
| 
 | ||||
| 	#AKTUALNI_ZADADNI_obrazek { | ||||
| 	& #AKTUALNI_ZADADNI_obrazek { | ||||
| 		margin-top: 15px; | ||||
| 	} | ||||
| 
 | ||||
| 	div.AKTUALNI_ZADANI_termin { | ||||
| 	& div.AKTUALNI_ZADANI_termin { | ||||
| 		text-align: center; | ||||
| 		font-size: large; | ||||
| 		font-weight: bold; | ||||
|  | @ -553,7 +553,7 @@ div.odpocet { | |||
| 			font-size: small; | ||||
| 		} | ||||
| 
 | ||||
| 		.AKTUALNI_ZADANI_datum { | ||||
| 		& .AKTUALNI_ZADANI_datum { | ||||
| 			color: var(--hlavni-oranzova); | ||||
| 			margin: 0; | ||||
| 		} | ||||
|  |  | |||
							
								
								
									
										731
									
								
								mamweb/static/css/mamweb_legacy.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										731
									
								
								mamweb/static/css/mamweb_legacy.css
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,731 @@ | |||
| @charset "utf-8"; /* vynuť utf-8 */ | ||||
| 
 | ||||
| @supports (-webkit-touch-callout: none) and (not (offset-position: normal)) { | ||||
| 
 | ||||
| .button { | ||||
| 	margin: 10px 0 10px 0; | ||||
| 	padding: 4px 0; /*vertikální centování textu*/ | ||||
| 	text-align: center; | ||||
| 	background-color: var(--hlavni-oranzova); | ||||
| 	color: var(--barva-pozadi); | ||||
| 	font-size: 150%; | ||||
| 	font-weight: bold; | ||||
| 	font-variant: small-caps; | ||||
| 	filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); | ||||
| } | ||||
| .button:hover { | ||||
| 	position: relative; | ||||
| 	top: 2px; | ||||
| 	left: 2px; | ||||
| 	background-color: #df490e; | ||||
| } | ||||
| /******************/ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /* Rozložení webu a jeho prvky (hlavička, menu, footer) */ | ||||
| 
 | ||||
| /**** KONTEJNER ****/ | ||||
| div.kontejner { /* Ne container, aby se to netlouklo s bootstrapem. */ | ||||
| 	width: 970px; | ||||
| 	margin: auto; | ||||
| 	min-height: 100vh; | ||||
| 	position: relative; | ||||
| 	padding: 0; | ||||
| } | ||||
| 
 | ||||
| .org-logged-in div.kontejner { | ||||
| 	margin-top: var(--login-bar-height); | ||||
| } | ||||
| 
 | ||||
| div.kontejner div.kontent-wrapper { | ||||
| 	padding-bottom: var(--footer-height); | ||||
| } | ||||
| 
 | ||||
| div.kontejner div.kontent-wrapper div.kontent { | ||||
| 	padding: 15px 30px; | ||||
| } | ||||
| 
 | ||||
| /* Roztáhne obsah z containeru na celou šířku obrazovky: */ | ||||
| .full_width { | ||||
| 	width: 100vw; | ||||
| 	margin-left: calc(-50vw + 485px); | ||||
| } | ||||
| 
 | ||||
| /* Na úzkém displeji nechceme nic dělat. */ | ||||
| @media(max-width: 860px) { | ||||
| 	.full_width { | ||||
| 		margin-left: 0; | ||||
| 		width: unset; | ||||
| 	} | ||||
| } | ||||
| /*******************/ | ||||
| 
 | ||||
| 
 | ||||
| /**** HLAVIČKA ****/ | ||||
| #header { | ||||
| 	position: relative; | ||||
| 	background: url("../images/header/vikendovka.jpg") no-repeat center top; /* poměr 350:970, TODO: aby to nemuselo být přesně na pixely */ | ||||
| 	background-size: 100%; | ||||
| 	top: 58px; | ||||
| } | ||||
| 
 | ||||
| #header img.logo { | ||||
| 	width: 100%; | ||||
| 	filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); | ||||
| } | ||||
| 
 | ||||
| #header img.logo-mobile { | ||||
| 	display: none; | ||||
| } | ||||
| 
 | ||||
| #header .no-mobile { | ||||
| 	background-size: contain; | ||||
| } | ||||
| /******************/ | ||||
| 
 | ||||
| 
 | ||||
| /**** Footer ****/ | ||||
| #footer { | ||||
| 	position: absolute; | ||||
| 	bottom: 0; | ||||
| 	width: 100%; | ||||
| 	background: url("../images/mozaika-footer.svg") no-repeat top center; | ||||
| 	height: var(--footer-height); | ||||
| 	background-size: 100%; | ||||
| 	filter: drop-shadow(5px 0px 5px rgba(0, 0, 0, 0.4)); | ||||
| 	padding-top: 3.5%; | ||||
| } | ||||
| 
 | ||||
| #footer p.license { | ||||
| 	text-align: center; | ||||
| 	font-weight: 400; | ||||
| 	bottom: 0; | ||||
| } | ||||
| 
 | ||||
| #footer p.license a { | ||||
| 	color: #333; | ||||
| } | ||||
| 
 | ||||
| @media (max-width: 650px) { | ||||
| 	#footer { | ||||
| 		display: none; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| p.license-mobile { | ||||
| 	display: none; | ||||
| 	margin-bottom: 0; | ||||
| } | ||||
| 
 | ||||
| @media (max-width: 650px) { | ||||
| 	p.license-mobile { | ||||
| 		position: relative; | ||||
| 		display: block; | ||||
| 		font-size: 90%; | ||||
| 		background-color: var(--hlavni-oranzova); | ||||
| 		padding: 5%; | ||||
| 		text-align: justify; | ||||
| 	} | ||||
| } | ||||
| /****************/ | ||||
| 
 | ||||
| 
 | ||||
| /**** LOGIN BAR ****/ | ||||
| div.login-bar { | ||||
| 	background: var(--orgovska-fialova); | ||||
| 	color: var(--svetla-oranzova); | ||||
| 	width: 100%; | ||||
| 
 | ||||
| 	position: fixed; | ||||
| 	margin-top: calc(-1 * var(--login-bar-height)); | ||||
| 	min-height: var(--login-bar-height); | ||||
| 	z-index: 4086; | ||||
| 
 | ||||
| 	padding-left: 5px; | ||||
| 	padding-right: 5px; | ||||
| } | ||||
| 
 | ||||
| div.login-bar div { | ||||
| 	display: inline; | ||||
| } | ||||
| 
 | ||||
| div.login-bar a.LOGIN-ref-admin { | ||||
| 	display: inline; | ||||
| 	color: var(--barva-pozadi); | ||||
| } | ||||
| 
 | ||||
| div.login-bar .LOGIN_napis-webarum { | ||||
| 	display: inline; | ||||
| 	color: var(--barva-pozadi); | ||||
| 	float: right; | ||||
| } | ||||
| 
 | ||||
| div.login-bar .LOGIN_napis-webarum a { | ||||
| 	color: var(--svetla-oranzova); | ||||
| 	text-decoration: underline; | ||||
| } | ||||
| /*******************/ | ||||
| 
 | ||||
| 
 | ||||
| /* stránka přes celý displej */ | ||||
| @media (max-width: 970px) { | ||||
| 	#header { | ||||
| 		background-size: 100%; | ||||
| 	} | ||||
| 
 | ||||
| 	#header img.logo { | ||||
| 		width: 100%; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* malý tablet, mobil */ | ||||
| @media (max-width: 650px) { | ||||
| 	#header { | ||||
| 		width: 100%; | ||||
| 		top: 0; | ||||
| 		background-image: none; | ||||
| 	} | ||||
| 
 | ||||
| 	#header img.logo { | ||||
| 		display: none; | ||||
| 	} | ||||
| 
 | ||||
| 	#header img.logo-mobile { | ||||
| 		display: block; | ||||
| 		top: 0; | ||||
| 		left: 0; | ||||
| 		width: 100%; | ||||
| 		filter: drop-shadow(0px 0 5px rgba(0, 0, 0, 0.4)); | ||||
| 		margin-bottom: 3px; | ||||
| 	} | ||||
| 
 | ||||
| 	#header .no-mobile{ | ||||
| 		display: none; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /**** MENU ****/ | ||||
| 
 | ||||
| ul.menu { | ||||
| 	width: 100%; | ||||
| 	padding: 0; | ||||
| 	margin-top: -5px; /* posune celé menu nahoru (pak potřeba zvětšit mezeru mezi menu a submenu) */ | ||||
| 
 | ||||
| 	font-variant: small-caps; | ||||
| } | ||||
| 
 | ||||
| ul.menu a { | ||||
| 	text-decoration: none; | ||||
| 	font-weight: bold; | ||||
| 	font-size: 105%; | ||||
| } | ||||
| 
 | ||||
| ul.menu li { | ||||
| 	margin: 0; | ||||
| 	display: inline-block; | ||||
| 	width: 16.666667%; | ||||
| 	text-align: center; | ||||
| 
 | ||||
| 	font-size: 140%; | ||||
| 	font-weight: 400; | ||||
| } | ||||
| 
 | ||||
| ul.menu li >a:hover, >a:active { | ||||
| 	color: black; | ||||
| } | ||||
| 
 | ||||
| ul.menu li.active>a { | ||||
| 	color: var(--svetla-oranzova); | ||||
| } | ||||
| 
 | ||||
| ul.menu ul.submenu { | ||||
| 	background-color: var(--hlavni-oranzova); | ||||
| 	margin-top: 10px; /* mezera mezi hlavním menu a submenu */ | ||||
| 	margin-bottom: 10px; | ||||
| 	padding-top: 10px; | ||||
| 	padding-bottom: 5px; | ||||
| 	filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); | ||||
| 
 | ||||
| 	z-index: 50; | ||||
| 	font-weight: 400; | ||||
| } | ||||
| 
 | ||||
| ul.menu ul.submenu li { | ||||
| 	width: auto; | ||||
| 	padding: 0 20px 0 20px; | ||||
| 	display: inline-block; | ||||
| } | ||||
| 
 | ||||
| ul.menu ul.submenu li >a { | ||||
| 	color: var(--svetla-oranzova); | ||||
| 	text-decoration: none; | ||||
| 	text-shadow: none; | ||||
| } | ||||
| 
 | ||||
| ul.menu ul.submenu li >a :hover { | ||||
| 	color: black; | ||||
| } | ||||
| 
 | ||||
| ul.menu ul.submenu li.active>a, .parentactive ul li:first-child>a { | ||||
| 	color: black; | ||||
| } | ||||
| 
 | ||||
| @media (max-width: 970px) { | ||||
| 	ul.menu { | ||||
| 		font-size: 90%; | ||||
| 		margin-top: -7px; | ||||
| 	} | ||||
| 
 | ||||
| 	ul.menu li { | ||||
| 		margin-top: 10px; /* posunutí textu hlavního menu níže */ | ||||
| 	} | ||||
| 
 | ||||
| 	ul.submenu { | ||||
| 		margin-top: 8px; /* mezera mezi hlavním menu a submenu */ | ||||
| 	} | ||||
| 
 | ||||
| 	ul.submenu li { | ||||
| 		margin-top: 0; /* aby se spolu s textem hlavního menu neposunoval níže i text submenu */ | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @media(max-width: 800px) { | ||||
| 	ul.menu { | ||||
| 		font-size: 80%; | ||||
| 		margin-top: -2px; | ||||
| 	} | ||||
| 
 | ||||
| 	ul.menu li { | ||||
| 		margin-top: 10px; /* posunutí textu hlavního menu níže */ | ||||
| 	} | ||||
| 
 | ||||
| 	ul.submenu { | ||||
| 		margin-top: 8px; /* mezera mezi hlavním menu a submenu */ | ||||
| 	} | ||||
| 	ul.submenu li { | ||||
| 		margin-top: 0; /* aby se spolu s textem hlavního menu neposunoval níže i text submenu */ | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @media (max-width: 650px) { | ||||
| 	ul.menu { | ||||
| 		display: none; | ||||
| 	} | ||||
| 
 | ||||
| 	ul.menu_mobile { | ||||
| 		display: block; | ||||
| 		z-index: 10; | ||||
| 		position: sticky; | ||||
| 		font-variant: small-caps; | ||||
| 		font-size: 150%; | ||||
| 		font-weight: bold; | ||||
| 		list-style-type: none; | ||||
| 		padding-top: 3px; | ||||
| 		padding-bottom: 3px; | ||||
| 		padding-left: 12px; | ||||
| 	} | ||||
| 
 | ||||
| 	ul.menu_mobile a:active, ul.menu_mobile a:hover, ul.menu_mobile a:focus { | ||||
| 		text-decoration: none; | ||||
| 		color: black; | ||||
| 	} | ||||
| 
 | ||||
| 	ul.menu_mobile ul { | ||||
| 		list-style-type: none; | ||||
| 		font-size: 90%; | ||||
| 		color: black; /*černé šipky submenu*/ | ||||
| 	} | ||||
| 
 | ||||
| 	ul.menu_mobile ul li > a { | ||||
| 		color: black; | ||||
| 	} | ||||
| 
 | ||||
| 	ul.menu_mobile ul li::before { | ||||
| 		content: ' \276D  '; /*https://www.w3schools.com/cssref/css_entities.asp*/ | ||||
| 	} | ||||
| 
 | ||||
| 	ul.menu_mobile br { | ||||
| 		display: none; | ||||
| 	} | ||||
| } /* konec @media */ | ||||
| /**************/ | ||||
| 
 | ||||
| /**** ZBYTEK ****/ | ||||
| /* (konkrétní stránky) */ | ||||
| 
 | ||||
| /* Titulní stránka */ | ||||
| .titulnistrana { | ||||
| 	display: flex; | ||||
| 	text-align: justify; | ||||
| 
 | ||||
| @media(max-width: 800px){ | ||||
| 	.titulnistrana { | ||||
| 		display: block; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .titulnistrana h1 { text-align: center; } | ||||
| 
 | ||||
| .titulnistrana .TITULNI_STRANA_zjistit_vic { | ||||
| 	text-align: center; | ||||
| 	margin-bottom: 30px; | ||||
| } | ||||
| 
 | ||||
| .titulnistrana .TITULNI_STRANA_zjistit_vic hr { | ||||
| 	display: none; | ||||
| } | ||||
| 
 | ||||
| @media(max-width: 800px){ | ||||
| 	.titulnistrana .TITULNI_STRANA_zjistit_vic hr { | ||||
| 		display: flex; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @media(max-width: 800px) { | ||||
| 	.titulnistrana .TITULNI_STRANA_graf { | ||||
| 		padding-top: 40px; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .titulnistrana .TITULNI_STRANA_graf .TITULNI_STRANA_graf-svg { | ||||
| 	display: flex; | ||||
| } | ||||
| 
 | ||||
| .titulnistrana .TITULNI_STRANA_graf .TITULNI_STRANA_graf-svg #svg-graf { | ||||
| 	width: 100%; | ||||
| 	height: auto; | ||||
| 	margin: 30px; | ||||
| } | ||||
| 
 | ||||
| @media(max-width: 800px){ | ||||
| 	.titulnistrana .TITULNI_STRANA_graf .TITULNI_STRANA_graf-svg #svg-graf { | ||||
| 		max-width: 500px; | ||||
| 		padding: 10px; | ||||
| 		margin: auto; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .titulnistrana .TITULNI_STRANA_obsah { | ||||
| 	width: 66%; | ||||
| } | ||||
| 
 | ||||
| @media(max-width: 800px){ | ||||
| 	.titulnistrana .TITULNI_STRANA_obsah { | ||||
| 		width: 100%; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .titulnistrana .TITULNI_STRANA_vitej_titulka, .TITULNI_STRANA_temata_titulka { | ||||
| 	width: 49%; | ||||
| 	padding: 10px; | ||||
| 	display: table-cell; | ||||
| } | ||||
| 
 | ||||
| @media (max-width: 650px) { | ||||
| 	.titulnistrana .TITULNI_STRANA_vitej_titulka, .TITULNI_STRANA_temata_titulka { | ||||
| 		width: 100%; | ||||
| 		display: block; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .titulnistrana .TITULNI_STRANA_novinky { | ||||
| 	width: 33%; | ||||
| 	padding: 10px; | ||||
| } | ||||
| 
 | ||||
| @media(max-width: 800px){ | ||||
| 	.titulnistrana .TITULNI_STRANA_novinky { | ||||
| 			width: 100%; | ||||
| 			max-width: 500px; | ||||
| 			margin: auto; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Stránky Aktuální ročník */ | ||||
| .stranka_aktualni_zadani { | ||||
| 	text-align: center; | ||||
| } | ||||
| 
 | ||||
| .stranka_aktualni_zadani #AKTUALNI_ZADADNI_obrazek { | ||||
| 	margin-top: 15px; | ||||
| } | ||||
| 
 | ||||
| .stranka_aktualni_zadani div.AKTUALNI_ZADANI_termin { | ||||
| 	text-align: center; | ||||
| 	font-size: large; | ||||
| 	font-weight: bold; | ||||
| } | ||||
| 
 | ||||
| @media (max-width: 420px) { | ||||
| 	.stranka_aktualni_zadani div.AKTUALNI_ZADANI_termin { | ||||
| 		font-size: small; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .stranka_aktualni_zadani .AKTUALNI_ZADANI_datum { | ||||
| 		color: var(--hlavni-oranzova); | ||||
| 		margin: 0; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Stránka Jak řešit */ | ||||
| .jakresit svg { | ||||
| 	width: 33%; | ||||
| 	padding: 10px; | ||||
| 	filter: none; | ||||
| } | ||||
| 
 | ||||
| @media(max-width: 860px) { | ||||
| 	.jakresit svg { | ||||
| 		margin: auto; | ||||
| 		display: grid; | ||||
| 		width: 100%; | ||||
| 		max-width: 360px; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /**** OZNAČENÍ NE-PUBLIC ČÁSTÍ ****/ | ||||
| .mam-org-only { | ||||
| 	background: var(--orgovska-svetla-fialova); | ||||
| 	padding: 10px; | ||||
| 	margin: 10px -10px; | ||||
| 	border: var(--orgovska-fialova) 2px dashed; | ||||
| } | ||||
| 
 | ||||
| .mam-org-only .mam-org-only { | ||||
| 	border: 0; | ||||
| } | ||||
| 
 | ||||
| .mam-org-only li { | ||||
| 	padding: 3px 0; | ||||
| 	margin: -2px 0; | ||||
| } | ||||
| /**********************************/ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /**** OTÁČECÍ KARTY ****/ | ||||
| /* (orgové, archiv) */ | ||||
| .flip-card { | ||||
| 	perspective: 1000px; /* Remove this if you don't want the 3D effect */ | ||||
| 	margin-left: auto; | ||||
| 	margin-right: auto; | ||||
| } | ||||
| 
 | ||||
| 	/* This container is needed to position the front and back side */ | ||||
| .flip-card .flip-card-inner { | ||||
| 	position: relative; | ||||
| 	width: 100%; | ||||
| 	height: 100%; | ||||
| 	transition: transform 0.8s; | ||||
| 	transform-style: preserve-3d; | ||||
| } | ||||
| 
 | ||||
| 	/* Do an horizontal flip when you move the mouse over the flip box container */ | ||||
| .flip-card:hover .flip-card-inner { | ||||
| 	transform: rotateY(180deg); | ||||
| } | ||||
| 
 | ||||
| 	/* Position the front and back side */ | ||||
| .flip-card .flip-card-front, .flip-card-back { | ||||
| 	position: absolute; | ||||
| 	width: 100%; | ||||
| 	height: 100%; | ||||
| 	-webkit-backface-visibility: hidden; /* Safari */ | ||||
| 	backface-visibility: hidden; | ||||
| } | ||||
| 
 | ||||
| .flip-card div.flip-card-foto, div.flip-card-foto img { | ||||
| 	width: 100%; | ||||
| 	height: 100%; | ||||
| 
 | ||||
| 	/* Pokud je na přední straně něco proklikávacího (třeba celá fotka), tak na dotykových zařízeních nemůže proklikávat, aby se dalo otáčet */ | ||||
| @media(hover: none) { | ||||
| 	.flip-card div.flip-card-foto, div.flip-card-foto img a { pointer-events: none; } | ||||
| } | ||||
| 
 | ||||
| 	/* Style the back side */ | ||||
| 	.flip-card-back { | ||||
| 		transform: rotateY(180deg); | ||||
| 		padding: 10px; | ||||
| 		padding-top: 20px; | ||||
| 	} | ||||
| } | ||||
| /***********************/ | ||||
| 
 | ||||
| 
 | ||||
| /**** TABULKY ****/ | ||||
| 
 | ||||
| /** Tabulka s čárami mezi sloupci **/ | ||||
| /* Např. výsledkovky */ | ||||
| 
 | ||||
| .tabulka_oramovane_sloupce { | ||||
| 	border: solid 2px; | ||||
| } | ||||
| 
 | ||||
| .tabulka_oramovane_sloupce td:first-child, .tabulka_oramovane_sloupce th:first-child { | ||||
| 	border-left: none; | ||||
| 	border-right: solid 1px; | ||||
| } | ||||
| 
 | ||||
| .tabulka_oramovane_sloupce td:nth-child(2), .tabulka_oramovane_sloupce th:nth-child(2) { | ||||
| 	border-left: none; | ||||
| } | ||||
| 
 | ||||
| .tabulka_oramovane_sloupce td, .tabulka_oramovane_sloupce th { | ||||
| 	padding: 0.1em 0.3em; | ||||
| 	border-left: solid 1px; | ||||
| } | ||||
| 
 | ||||
| .tabulka_oramovane_sloupce thead th, .tabulka_oramovane_sloupce thead td { | ||||
| 	border-bottom: solid 1px; | ||||
| } | ||||
| /***********************************/ | ||||
| 
 | ||||
| 
 | ||||
| /** Tabulka se střídajícími se barvami řádků **/ | ||||
| /* Skoro jakákoliv tabulka kromě výsledkovek */ | ||||
| 
 | ||||
| .barevna_tabulka td th { | ||||
| 	padding: 1px 10px 1px 10px; | ||||
| } | ||||
| 
 | ||||
| .barevna_tabulka tbody tr:nth-child(even), thead tr { | ||||
| 	background: var(--svetlounka-oranzova); | ||||
| } | ||||
| 
 | ||||
| .barevna_tabulka tbody tr:nth-child(odd) { | ||||
| 	background: var(--barva-pozadi); | ||||
| } | ||||
| /**********************************************/ | ||||
| 
 | ||||
| 
 | ||||
| /** Tabulka, kde první řádek a sloupec je pořád vidět **/ | ||||
| /* Např. tabulka odevzdaných řešení, nebo výsledkovky */ | ||||
| .tabulka_s_uchycenym_radkem_a_sloupcem { | ||||
| 	/* Omezí výšku a šířku, aby bylo příjemné na scrollování a zapne scrollování */ | ||||
| 	display: block; | ||||
| 	width: fit-content; /* display: block; roztahuje na celou šířku */ | ||||
| 	max-height: 80vh; | ||||
| 	overflow: auto; | ||||
| 	max-width: 90%; /* (FIXME asi není potřeba u tabulek, co nejsou na celou obrazovku) */ | ||||
| 	margin-left: 5%; /* Vystředování (FIXME není potřeba u tabulek, co nejsou na celou obrazovku) */ | ||||
| 
 | ||||
| 	border-collapse: separate; /* Pokud má tabulka orámování, je potřeba ho separovat, aby dodrželo position: sticky; */ | ||||
| 	border-spacing: 0; | ||||
| } | ||||
| 
 | ||||
| 	/* Uchytí první řádek */ | ||||
| .tabulka_s_uchycenym_radkem_a_sloupcem thead tr { | ||||
| 	position: sticky; | ||||
| 	top: 0; | ||||
| 	z-index: 2; | ||||
| } | ||||
| 
 | ||||
| 	/* Uchytí první sloupec */ | ||||
| .tabulka_s_uchycenym_radkem_a_sloupcem td:first-child, .tabulka_s_uchycenym_radkem_a_sloupcem th:first-child { | ||||
| 	position: sticky; | ||||
| 	left: 0; | ||||
| 	background: inherit; /* (Snad) zneprůhlední první sloupec */ | ||||
| 	z-index: 1; | ||||
| } | ||||
| /*******************************************************/ | ||||
| 
 | ||||
| /** Tabulka mající všechna ohraničení **/ | ||||
| .plne_ohranicena_tabulka { | ||||
| 	border-collapse: collapse; | ||||
| } | ||||
| 
 | ||||
| .plne_ohranicena_tabulka tr th, .plne_ohranicena_tabulka tr td { | ||||
| 	border: 1px solid black; | ||||
| 	padding: 1px 10px 1px 10px; | ||||
| } | ||||
| /***************************************/ | ||||
| 
 | ||||
| /** Výsledkovky **/ | ||||
| .vysledkovka, .tabulka_oramovane_sloupce td:first-child, .vysledkovka, .tabulka_oramovane_sloupce th:first-child { position: unset; } | ||||
| .vysledkovka, .tabulka_oramovane_sloupce td:nth-child(2), .vysledkovka, .tabulka_oramovane_sloupce th:nth-child(2) { | ||||
| 	border-right: solid 1px; | ||||
| 
 | ||||
| 	position: sticky; | ||||
| 	left: 0; | ||||
| 	background: inherit; /* (Snad) zneprůhlední druhý sloupec */ | ||||
| 	z-index: 1; | ||||
| } | ||||
| .vysledkovka, .tabulka_oramovane_sloupce td:nth-child(3), .vysledkovka, .tabulka_oramovane_sloupce th:nth-child(3) { | ||||
| 		border-left: none; | ||||
| } | ||||
| /*****************/ | ||||
| 
 | ||||
| 
 | ||||
| /** Tabulka mých (řešitelových) řešení **/ | ||||
| .moje_reseni tr th, .moje_reseni tr td { | ||||
| 	text-align: center; | ||||
| } | ||||
| 
 | ||||
| .moje_reseni tr td.problem { text-align: left; } | ||||
| /****************************************/ | ||||
| 
 | ||||
| 
 | ||||
| /** Detail řešení **/ | ||||
| .bodovani>input { | ||||
| 	width: 4em; | ||||
| } | ||||
| 
 | ||||
| .bodovani>input::placeholder { | ||||
| 	color: lightgray; | ||||
| 	opacity: 1; | ||||
| } | ||||
| 
 | ||||
| .bodovani>input::-webkit-input-placeholder { /* Edge */ | ||||
| 	color: lightgray; | ||||
| } | ||||
| 
 | ||||
| /*******************/ | ||||
| /*****************/ | ||||
| 
 | ||||
| 
 | ||||
| .novinka .novinka_obrazek { | ||||
| 	margin: 10px 0 10px 0; | ||||
| 	width: 100%; | ||||
| } | ||||
| 
 | ||||
| .novinka .novinka_datum { | ||||
| 	font-weight: bold; | ||||
| } | ||||
| 
 | ||||
| .novinka .novinka_autor { | ||||
| 	text-align: right; | ||||
| 	font-style: italic; | ||||
| } | ||||
| 
 | ||||
| /**** FORMULÁŘE ****/ | ||||
| div.gdpr { | ||||
| 	font-size: 6pt; | ||||
| } | ||||
| 
 | ||||
| div.gdpr p { | ||||
| 	font-size: 6pt; | ||||
| 	margin-bottom: .66em; | ||||
| } | ||||
| 
 | ||||
| /*******************/ | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -57,7 +57,7 @@ | |||
| 	margin-right: auto; | ||||
| 
 | ||||
| 	/* This container is needed to position the front and back side */ | ||||
| 	.flip-card-inner { | ||||
| 	& .flip-card-inner { | ||||
| 		position: relative; | ||||
| 		width: 100%; | ||||
| 		height: 100%; | ||||
|  | @ -71,7 +71,7 @@ | |||
| 	} | ||||
| 
 | ||||
| 	/* Position the front and back side */ | ||||
| 	.flip-card-front, .flip-card-back { | ||||
| 	& .flip-card-front, & .flip-card-back { | ||||
| 		position: absolute; | ||||
| 		width: 100%; | ||||
| 		height: 100%; | ||||
|  | @ -79,18 +79,18 @@ | |||
| 		backface-visibility: hidden; | ||||
| 	} | ||||
| 
 | ||||
| 	div.flip-card-foto, div.flip-card-foto img { | ||||
| 	& div.flip-card-foto, & div.flip-card-foto img { | ||||
| 		width: 100%; | ||||
| 		height: 100%; | ||||
| 
 | ||||
| 		/* Pokud je na přední straně něco proklikávacího (třeba celá fotka), tak na dotykových zařízeních nemůže proklikávat, aby se dalo otáčet */ | ||||
| 		@media(hover: none) { | ||||
| 			a { pointer-events: none; } | ||||
| 			& a { pointer-events: none; } | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Style the back side */ | ||||
| 	.flip-card-back { | ||||
| 	& .flip-card-back { | ||||
| 		transform: rotateY(180deg); | ||||
| 		padding: 10px; | ||||
| 		padding-top: 20px; | ||||
|  | @ -203,7 +203,7 @@ div.org_email { | |||
| .tabulka_oramovane_sloupce { | ||||
| 	border: solid 2px; | ||||
| 
 | ||||
| 	td, th { | ||||
| 	& td, & th { | ||||
| 		&:first-child, &:first-child { | ||||
| 			border-left: none; | ||||
| 			border-right: solid 1px; | ||||
|  | @ -217,7 +217,7 @@ div.org_email { | |||
| 		border-left: solid 1px; | ||||
| 	} | ||||
| 
 | ||||
| 	thead { th, td { | ||||
| 	& thead { & th, & td { | ||||
| 			border-bottom: solid 1px; | ||||
| 	} } | ||||
| } | ||||
|  | @ -228,15 +228,15 @@ div.org_email { | |||
| /* Skoro jakákoliv tabulka kromě výsledkovek */ | ||||
| 
 | ||||
| .barevna_tabulka { | ||||
| 	td th { | ||||
| 	& td th { | ||||
| 		padding: 1px 10px 1px 10px; | ||||
| 	} | ||||
| 
 | ||||
| 	tbody tr:nth-child(even), thead tr { | ||||
| 	& tbody tr:nth-child(even), & thead tr { | ||||
| 		background: var(--svetlounka-oranzova); | ||||
| 	} | ||||
| 
 | ||||
| 	tbody tr:nth-child(odd) { | ||||
| 	& tbody tr:nth-child(odd) { | ||||
| 		background: var(--barva-pozadi); | ||||
| 	} | ||||
| } | ||||
|  | @ -258,14 +258,14 @@ div.org_email { | |||
| 	border-spacing: 0; | ||||
| 
 | ||||
| 	/* Uchytí první řádek */ | ||||
| 	thead tr { | ||||
| 	& thead tr { | ||||
| 		position: sticky; | ||||
| 		top: 0; | ||||
| 		z-index: 2; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Uchytí první sloupec */ | ||||
| 	td, th { &:first-child { | ||||
| 	& td, & th { &:first-child { | ||||
| 		position: sticky; | ||||
| 		left: 0; | ||||
| 		background: inherit; /* (Snad) zneprůhlední první sloupec */ | ||||
|  | @ -290,7 +290,7 @@ div.org_email { | |||
| .plne_ohranicena_tabulka { | ||||
| 	border-collapse: collapse; | ||||
| 
 | ||||
| 	tr { th, td { | ||||
| 	& tr { & th, & td { | ||||
| 		border: 1px solid black; | ||||
| 		padding: 1px 10px 1px 10px; | ||||
| 	} } | ||||
|  | @ -305,7 +305,7 @@ div.org_email { | |||
| 
 | ||||
| /** Výsledkovky **/ | ||||
| .vysledkovka, .tabulka_oramovane_sloupce { | ||||
| 	td, th { | ||||
| 	& td, & th { | ||||
| 		&:first-child { position: unset; } | ||||
| 
 | ||||
| 		&:nth-child(2) { | ||||
|  | @ -327,11 +327,11 @@ div.org_email { | |||
| 
 | ||||
| /** Tabulka mých (řešitelových) řešení **/ | ||||
| .moje_reseni tr { | ||||
| 	th, td { | ||||
| 	& th, & td { | ||||
| 		text-align: center; | ||||
| 	} | ||||
| 
 | ||||
| 	td.problem { text-align: left; } | ||||
| 	& td.problem { text-align: left; } | ||||
| } | ||||
| 
 | ||||
| /* Různá šířka problému */ | ||||
|  | @ -378,16 +378,16 @@ div.org_email { | |||
| 
 | ||||
| 
 | ||||
| .novinka { | ||||
| 	.novinka_obrazek { | ||||
| 	& .novinka_obrazek { | ||||
| 		margin: 10px 0 10px 0; | ||||
| 		width: 100%; | ||||
| 	} | ||||
| 
 | ||||
| 	.novinka_datum { | ||||
| 	& .novinka_datum { | ||||
| 		font-weight: bold; | ||||
| 	} | ||||
| 
 | ||||
| 	.novinka_autor { | ||||
| 	& .novinka_autor { | ||||
| 		text-align: right; | ||||
| 		font-style: italic; | ||||
| 	} | ||||
|  | @ -413,7 +413,6 @@ table#reseni.form td,  table#reseni.form tr { | |||
| } | ||||
| 
 | ||||
| @media(max-width: 800px) { | ||||
| 
 | ||||
| 	table#reseni.form td, table#reseni.form tr { | ||||
| 		display: inline-grid; | ||||
| 		max-width: 300px; | ||||
|  | @ -473,7 +472,7 @@ ul.form li{ | |||
| div.gdpr { | ||||
| 	font-size: 6pt; | ||||
| 
 | ||||
| 	p { | ||||
| 	& p { | ||||
| 		font-size: 6pt; | ||||
| 		margin-bottom: .66em; | ||||
| 	} | ||||
|  |  | |||
|  | @ -8,11 +8,12 @@ | |||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <link rel="shortcut icon" href="{% static 'images/MATFYZ_MM_barevne.svg' %}" type="image/x-icon"> | ||||
|     {% block custom_css %}{% endblock %} | ||||
|     <link href="{% static 'bootstrap/css/bootstrap.css' %}?version=2" rel="stylesheet"> | ||||
|     <link href="{% static 'css/constants.css' %}?version=2" rel="stylesheet"> | ||||
|     <link href="{% static 'css/base.css' %}?version=2" rel="stylesheet"> | ||||
|     <link href="{% static 'css/layout.css' %}?version=2" rel="stylesheet"> | ||||
|     <link href="{% static 'css/modules.css' %}?version=2" rel="stylesheet"> | ||||
|     <link href="{% static 'bootstrap/css/bootstrap.css' %}?version=3" rel="stylesheet"> | ||||
|     <link href="{% static 'css/constants.css' %}?version=3" rel="stylesheet"> | ||||
|     <link href="{% static 'css/mamweb_legacy.css' %}?version=3" rel="stylesheet"> | ||||
|     <link href="{% static 'css/base.css' %}?version=3" rel="stylesheet"> | ||||
|     <link href="{% static 'css/layout.css' %}?version=3" rel="stylesheet"> | ||||
|     <link href="{% static 'css/modules.css' %}?version=3" rel="stylesheet"> | ||||
|     <script src="{% static 'js/jquery-1.11.1.js' %}"></script> | ||||
|     <script src="{% static 'js/jquery-3.4.1.js' %}"></script> | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
|   {% if not novinka.zverejneno and user.je_org %} | ||||
|   <div class="mam-org-only"> | ||||
|     <ul> | ||||
|       <li><a href="/admin/seminar/novinky/{{novinka.pk}}">Upravit novinku</a> | ||||
|       <li><a href="{% url 'admin:novinky_novinky_change' novinka.pk %}">Upravit novinku</a> | ||||
|     </ul> | ||||
|   {% endif %} | ||||
|   {% if novinka.zverejneno or user.je_org %} | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| from django.contrib import admin | ||||
| from django_reverse_admin import ReverseModelAdmin | ||||
| import seminar.models as m | ||||
| import odevzdavatko.models as m | ||||
| 
 | ||||
| 
 | ||||
| class PrilohaReseniInline(admin.TabularInline): | ||||
|  |  | |||
|  | @ -4,8 +4,11 @@ from django.forms import formset_factory | |||
| from django.forms.models import inlineformset_factory | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| from seminar.models import Resitel | ||||
| import seminar.models as m | ||||
| from personalni.models import Resitel | ||||
| from tvorba.models import Problem, Deadline | ||||
| from various.models import Nastaveni | ||||
| 
 | ||||
| from odevzdavatko.models import Reseni, PrilohaReseni, Hodnoceni | ||||
| 
 | ||||
| import logging | ||||
| 
 | ||||
|  | @ -22,7 +25,7 @@ class DateInput(forms.DateInput): | |||
| 
 | ||||
| class PosliReseniForm(forms.Form): | ||||
| 	problem = forms.ModelMultipleChoiceField( | ||||
| 		queryset=m.Problem.objects.all(), | ||||
| 		queryset=Problem.objects.all(), | ||||
| 		label="Problémy", | ||||
| 		widget=autocomplete.ModelSelect2Multiple( | ||||
| 			url='autocomplete_problem', | ||||
|  | @ -58,7 +61,7 @@ class PosliReseniForm(forms.Form): | |||
| 
 | ||||
| 	#cas_doruceni = models.DateTimeField('čas_doručení', default=timezone.now, blank=True) | ||||
| 
 | ||||
| 	forma = forms.ChoiceField(label="Forma řešení",choices = m.Reseni.FORMA_CHOICES) | ||||
| 	forma = forms.ChoiceField(label="Forma řešení",choices = Reseni.FORMA_CHOICES) | ||||
| 	#forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False, | ||||
| 	#	 default=FORMA_EMAIL) | ||||
| 
 | ||||
|  | @ -69,7 +72,7 @@ class PosliReseniForm(forms.Form): | |||
| 
 | ||||
| class NahrajReseniForm(forms.ModelForm): | ||||
| 	class Meta: | ||||
| 		model = m.Reseni | ||||
| 		model = Reseni | ||||
| 		fields = ('problem', 'resitele') | ||||
| 		help_texts = {'problem':''} # Nezobrazovat help text ve formuláři | ||||
| 		 | ||||
|  | @ -109,11 +112,11 @@ class NahrajReseniForm(forms.ModelForm): | |||
| 	def clean_problem(self): | ||||
| 		problem = self.cleaned_data.get('problem') | ||||
| 		for p in problem: | ||||
| 			if p.stav != m.Problem.STAV_ZADANY: | ||||
| 			if p.stav != Problem.STAV_ZADANY: | ||||
| 				raise forms.ValidationError("Problém " + str(p) + " již nelze řešit!") | ||||
| 		return problem | ||||
| 
 | ||||
| ReseniSPrilohamiFormSet = inlineformset_factory(m.Reseni,m.PrilohaReseni,  | ||||
| ReseniSPrilohamiFormSet = inlineformset_factory(Reseni, PrilohaReseni, | ||||
| 		form = NahrajReseniForm, | ||||
| 		fields = ('soubor','res_poznamka'), | ||||
| 		widgets = {'res_poznamka':forms.TextInput()}, | ||||
|  | @ -125,7 +128,7 @@ ReseniSPrilohamiFormSet = inlineformset_factory(m.Reseni,m.PrilohaReseni, | |||
| 
 | ||||
| class JednoHodnoceniForm(forms.ModelForm): | ||||
| 	class Meta: | ||||
| 		model = m.Hodnoceni | ||||
| 		model = Hodnoceni | ||||
| 		fields = ('problem', 'body', 'deadline_body', 'feedback',) | ||||
| 		widgets = { | ||||
| 			'problem': autocomplete.ModelSelect2( | ||||
|  | @ -158,7 +161,7 @@ OhodnoceniReseniFormSet = formset_factory(JednoHodnoceniForm, | |||
| 
 | ||||
| class PoznamkaReseniForm(forms.ModelForm): | ||||
| 	class Meta: | ||||
| 		model = m.Reseni | ||||
| 		model = Reseni | ||||
| 		fields = ('poznamka',) | ||||
| 
 | ||||
| # FIXME: Ideálně by mělo být součástí třídy níž, ale neumím to udělat | ||||
|  | @ -198,7 +201,7 @@ class OdevzdavatkoTabulkaFiltrForm(forms.Form): | |||
| 		 | ||||
| 		from django.db.utils import OperationalError | ||||
| 		try: | ||||
| 			aktualni_rocnik = m.Nastaveni.get_solo().aktualni_rocnik | ||||
| 			aktualni_rocnik = Nastaveni.get_solo().aktualni_rocnik | ||||
| 		except OperationalError: | ||||
| 			# django.db.utils.OperationalError: no such table: seminar_nastaveni | ||||
| 			# Nemáme databázi, takže to selhalo. Pro jistotu vrátíme aspoň dvě možnosti, ať to nepadá dál | ||||
|  | @ -214,7 +217,7 @@ class OdevzdavatkoTabulkaFiltrForm(forms.Form): | |||
| 
 | ||||
| 		result.append(("0001-01-01", f"Odjakživa")) | ||||
| 
 | ||||
| 		for deadline in m.Deadline.objects.filter( | ||||
| 		for deadline in Deadline.objects.filter( | ||||
| 				deadline__lte=timezone.now(), | ||||
| 				cislo__rocnik=aktualni_rocnik | ||||
| 				).order_by("deadline"): | ||||
|  |  | |||
							
								
								
									
										99
									
								
								odevzdavatko/migrations/0001_create.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								odevzdavatko/migrations/0001_create.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,99 @@ | |||
| # Generated by Django 4.2.13 on 2024-10-22 22:51 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.utils.timezone | ||||
| import odevzdavatko.models | ||||
| 
 | ||||
| def nastav_nove_contenttypes(apps, schema_editor): | ||||
|     ContentType = apps.get_model('contenttypes', 'ContentType') | ||||
|     for m in ('reseni', 'hodnoceni', 'reseni_resitele', 'prilohareseni'): | ||||
|         ContentType.objects.filter(app_label='seminar', model=m).update(app_label='odevzdavatko') | ||||
| 
 | ||||
| def nastav_stare_contenttypes(apps, schema_editor): | ||||
|     ContentType = apps.get_model('contenttypes', 'ContentType') | ||||
|     for m in ('reseni', 'hodnoceni', 'reseni_resitele', 'prilohareseni'): | ||||
|         ContentType.objects.filter(app_label='odevzdavatko', model=m).update(app_label='seminar') | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     initial = True | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0132_unmanage_odevzdavatko'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name='Hodnoceni', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(primary_key=True, serialize=False)), | ||||
|                 ('body', models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='body')), | ||||
|                 ('feedback', models.TextField(blank=True, default='', help_text='Zpětná vazba řešiteli (plain text)', verbose_name='zpětná vazba')), | ||||
|                 ('cislo_body', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.cislo', verbose_name='číslo pro body')), | ||||
|                 ('deadline_body', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.deadline', verbose_name='deadline pro body')), | ||||
|                 ('problem', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.problem', verbose_name='problém')), | ||||
|                 ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='odevzdavatko.reseni', verbose_name='řešení')), | ||||
|             ], | ||||
|             options={ | ||||
|                 'verbose_name': 'Hodnocení', | ||||
|                 'verbose_name_plural': 'Hodnocení', | ||||
|                 'db_table': 'seminar_hodnoceni', | ||||
|                 'managed': False, | ||||
|             }, | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name='PrilohaReseni', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(primary_key=True, serialize=False)), | ||||
|                 ('vytvoreno', models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='vytvořeno')), | ||||
|                 ('soubor', models.FileField(upload_to=odevzdavatko.models.generate_filename, verbose_name='soubor')), | ||||
|                 ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k příloze řešení (plain text), např. o původu', verbose_name='neveřejná poznámka')), | ||||
|                 ('res_poznamka', models.TextField(blank=True, help_text='Poznámka k příloze řešení, např. co daný soubor obsahuje', verbose_name='poznámka řešitele')), | ||||
|                 ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='prilohy', to='odevzdavatko.reseni', verbose_name='řešení')), | ||||
|             ], | ||||
|             options={ | ||||
|                 'verbose_name': 'Příloha řešení', | ||||
|                 'verbose_name_plural': 'Přílohy řešení', | ||||
|                 'db_table': 'seminar_priloha_reseni', | ||||
|                 'ordering': ['reseni', 'vytvoreno'], | ||||
|                 'managed': False, | ||||
|             }, | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name='Reseni', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(primary_key=True, serialize=False)), | ||||
|                 ('cas_doruceni', models.DateTimeField(blank=True, default=django.utils.timezone.now, verbose_name='čas_doručení')), | ||||
|                 ('forma', models.CharField(choices=[('papir', 'Papírové řešení'), ('email', 'Emailem'), ('upload', 'Upload přes web')], default='email', max_length=16, verbose_name='forma řešení')), | ||||
|                 ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k řešení (plain text)', verbose_name='neveřejná poznámka')), | ||||
|                 ('zverejneno', models.BooleanField(default=False, help_text='Udává, zda je řešení zveřejněno', verbose_name='řešení zveřejněno')), | ||||
|                 ('problem', models.ManyToManyField(help_text='Problém', through='odevzdavatko.Hodnoceni', to='seminar.problem', verbose_name='problém')), | ||||
|                 ('resitele', models.ManyToManyField(help_text='Seznam autorů řešení', through='odevzdavatko.Reseni_Resitele', to='personalni.resitel', verbose_name='autoři řešení')), | ||||
|                 ('text_cely', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='seminar.reseninode', verbose_name='Plná verze textu řešení')), | ||||
|             ], | ||||
|             options={ | ||||
|                 'verbose_name': 'Řešení', | ||||
|                 'verbose_name_plural': 'Řešení', | ||||
|                 'db_table': 'seminar_reseni', | ||||
|                 'ordering': ['-cas_doruceni'], | ||||
|                 'managed': False, | ||||
|             }, | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name='Reseni_Resitele', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(primary_key=True, serialize=False)), | ||||
|                 ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='odevzdavatko.reseni', verbose_name='řešení')), | ||||
|                 ('resitele', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='personalni.resitel', verbose_name='řešitel')), | ||||
|             ], | ||||
|             options={ | ||||
|                 'verbose_name': 'Řešení řešitelů', | ||||
|                 'verbose_name_plural': 'Řešení řešitelů', | ||||
|                 'db_table': 'seminar_reseni_resitele', | ||||
|                 'ordering': ['reseni', 'resitele'], | ||||
|                 'managed': False, | ||||
|             }, | ||||
|         ), | ||||
|         migrations.RunPython(nastav_nove_contenttypes, nastav_stare_contenttypes), | ||||
| 
 | ||||
|     ] | ||||
							
								
								
									
										30
									
								
								odevzdavatko/migrations/0002_manage.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								odevzdavatko/migrations/0002_manage.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| # Generated by Django 4.2.13 on 2024-10-23 21:07 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('odevzdavatko', '0001_create'), | ||||
|         ('seminar', '0134_delete_odevzdavatko'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterModelOptions( | ||||
|             name='hodnoceni', | ||||
|             options={'verbose_name': 'Hodnocení', 'verbose_name_plural': 'Hodnocení'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='prilohareseni', | ||||
|             options={'ordering': ['reseni', 'vytvoreno'], 'verbose_name': 'Příloha řešení', 'verbose_name_plural': 'Přílohy řešení'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='reseni', | ||||
|             options={'ordering': ['-cas_doruceni'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='reseni_resitele', | ||||
|             options={'ordering': ['reseni', 'resitele'], 'verbose_name': 'Řešení řešitelů', 'verbose_name_plural': 'Řešení řešitelů'}, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										13
									
								
								odevzdavatko/migrations/0003_odstrel_odevzdavatka_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								odevzdavatko/migrations/0003_odstrel_odevzdavatka_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # Generated by Django 4.2.13 on 2024-10-23 21:10 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('odevzdavatko', '0002_manage'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										13
									
								
								odevzdavatko/migrations/0004_tvorba_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								odevzdavatko/migrations/0004_tvorba_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 01:06 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('odevzdavatko', '0003_odstrel_odevzdavatka_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										35
									
								
								odevzdavatko/migrations/0005_tvorba_relink.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								odevzdavatko/migrations/0005_tvorba_relink.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 13:18 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('tvorba', '0001_tvorba_create'), | ||||
|         ('odevzdavatko', '0004_tvorba_pre'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterField( | ||||
|             model_name='hodnoceni', | ||||
|             name='cislo_body', | ||||
|             field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='tvorba.cislo', verbose_name='číslo pro body'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='hodnoceni', | ||||
|             name='deadline_body', | ||||
|             field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='tvorba.deadline', verbose_name='deadline pro body'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='hodnoceni', | ||||
|             name='problem', | ||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='tvorba.problem', verbose_name='problém'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='reseni', | ||||
|             name='problem', | ||||
|             field=models.ManyToManyField(help_text='Problém', through='odevzdavatko.Hodnoceni', to='tvorba.problem', verbose_name='problém'), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								odevzdavatko/migrations/0006_tvorba_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								odevzdavatko/migrations/0006_tvorba_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 21:34 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('odevzdavatko', '0005_tvorba_relink'), | ||||
|         ('tvorba', '0003_tvorba_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										13
									
								
								odevzdavatko/migrations/0007_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								odevzdavatko/migrations/0007_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # Generated by Django 4.2.16 on 2024-11-02 19:45 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('odevzdavatko', '0006_tvorba_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										20
									
								
								odevzdavatko/migrations/0008_odstrel_treenode_relink.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								odevzdavatko/migrations/0008_odstrel_treenode_relink.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| # Generated by Django 4.2.16 on 2024-11-02 20:44 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('treenode', '0001_odstrel_treenode_create'), | ||||
|         ('odevzdavatko', '0007_odstrel_treenode_pre'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterField( | ||||
|             model_name='reseni', | ||||
|             name='text_cely', | ||||
|             field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='treenode.reseninode', verbose_name='Plná verze textu řešení'), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								odevzdavatko/migrations/0009_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								odevzdavatko/migrations/0009_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.16 on 2024-11-02 20:52 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('odevzdavatko', '0008_odstrel_treenode_relink'), | ||||
|         ('treenode', '0003_odstrel_treenode_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
|  | @ -9,16 +9,14 @@ from django.urls import reverse_lazy | |||
| from django.utils import timezone | ||||
| from django.conf import settings | ||||
| 
 | ||||
| from seminar.models import tvorba as am | ||||
| from seminar.models import treenode as tm | ||||
| from seminar.models import base as bm | ||||
| from tvorba.models import Problem, Deadline, Cislo, Uloha, aux_generate_filename | ||||
| from various.models import SeminarModelBase | ||||
| 
 | ||||
| from odevzdavatko.utils import vzorecek_na_prepocet, inverze_vzorecku_na_prepocet | ||||
| from personalni.models import Resitel | ||||
| 
 | ||||
| 
 | ||||
| @reversion.register(ignore_duplicates=True) | ||||
| class Reseni(bm.SeminarModelBase): | ||||
| class Reseni(SeminarModelBase): | ||||
| 
 | ||||
| 	class Meta: | ||||
| 		db_table = 'seminar_reseni' | ||||
|  | @ -31,7 +29,7 @@ class Reseni(bm.SeminarModelBase): | |||
| 	id = models.AutoField(primary_key = True) | ||||
| 
 | ||||
| 	# Ke každé dvojici řešní a problém existuje nanejvýš jedno hodnocení, doplnění vazby. | ||||
| 	problem = models.ManyToManyField(am.Problem, verbose_name='problém', help_text='Problém', | ||||
| 	problem = models.ManyToManyField(Problem, verbose_name='problém', help_text='Problém', | ||||
| 									 through='Hodnoceni') | ||||
| 
 | ||||
| 	resitele = models.ManyToManyField(Resitel, verbose_name='autoři řešení', | ||||
|  | @ -51,7 +49,7 @@ class Reseni(bm.SeminarModelBase): | |||
| 	forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False, | ||||
| 							 default=FORMA_EMAIL) | ||||
| 
 | ||||
| 	text_cely = models.OneToOneField('ReseniNode', verbose_name='Plná verze textu řešení', | ||||
| 	text_cely = models.OneToOneField('treenode.ReseniNode', verbose_name='Plná verze textu řešení', | ||||
| 									 blank=True, null=True, related_name="reseni_cely_set", | ||||
| 									 on_delete=models.PROTECT) | ||||
| 
 | ||||
|  | @ -81,7 +79,7 @@ class Reseni(bm.SeminarModelBase): | |||
| 	# NOTE: Potenciální DB HOG (bez select_related) | ||||
| 
 | ||||
| 	def deadline_reseni(self): | ||||
| 		return am.Deadline.objects.filter(deadline__gte=self.cas_doruceni).order_by("deadline").first() | ||||
| 		return Deadline.objects.filter(deadline__gte=self.cas_doruceni).order_by("deadline").first() | ||||
| 
 | ||||
| ## Pravdepodobne uz nebude potreba: | ||||
| #	def save(self, *args, **kwargs): | ||||
|  | @ -90,7 +88,7 @@ class Reseni(bm.SeminarModelBase): | |||
| #			self.cislo_body = self.problem.cislo_reseni | ||||
| #		super(Reseni, self).save(*args, **kwargs) | ||||
| 
 | ||||
| class Hodnoceni(bm.SeminarModelBase): | ||||
| class Hodnoceni(SeminarModelBase): | ||||
| 	class Meta: | ||||
| 		db_table = 'seminar_hodnoceni' | ||||
| 		verbose_name = 'Hodnocení' | ||||
|  | @ -103,16 +101,16 @@ class Hodnoceni(bm.SeminarModelBase): | |||
| 	body = models.DecimalField(max_digits=8, decimal_places=1, verbose_name='body', | ||||
| 							   blank=True, null=True) | ||||
| 
 | ||||
| 	cislo_body = models.ForeignKey(am.Cislo, verbose_name='číslo pro body', | ||||
| 	cislo_body = models.ForeignKey(Cislo, verbose_name='číslo pro body', | ||||
| 								   related_name='hodnoceni', blank=True, null=True, on_delete=models.PROTECT) | ||||
| 
 | ||||
| 	# V ročníku < 26 nastaveno na deadline vygenerovaný pro původní cislo_body | ||||
| 	deadline_body = models.ForeignKey(am.Deadline, verbose_name='deadline pro body', | ||||
| 	deadline_body = models.ForeignKey(Deadline, verbose_name='deadline pro body', | ||||
| 								   related_name='hodnoceni', blank=True, null=True, on_delete=models.PROTECT) | ||||
| 
 | ||||
| 	reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE) | ||||
| 
 | ||||
| 	problem = models.ForeignKey(am.Problem, verbose_name='problém', | ||||
| 	problem = models.ForeignKey(Problem, verbose_name='problém', | ||||
| 								related_name='hodnoceni', on_delete=models.PROTECT) | ||||
| 
 | ||||
| 	feedback = models.TextField('zpětná vazba', blank=True, default='', help_text='Zpětná vazba řešiteli (plain text)') | ||||
|  | @ -168,7 +166,7 @@ class Hodnoceni(bm.SeminarModelBase): | |||
| 
 | ||||
| 	@property | ||||
| 	def body_neprepocitane_max(self): | ||||
| 		if not isinstance(self.problem.get_real_instance(), am.Uloha): | ||||
| 		if not isinstance(self.problem.get_real_instance(), Uloha): | ||||
| 			return None | ||||
| 		return self.problem.uloha.max_body | ||||
| 
 | ||||
|  | @ -178,12 +176,12 @@ class Hodnoceni(bm.SeminarModelBase): | |||
| def generate_filename(self, filename): | ||||
| 	return os.path.join( | ||||
| 		settings.SEMINAR_RESENI_DIR, | ||||
| 		am.aux_generate_filename(self, filename) | ||||
| 		aux_generate_filename(self, filename) | ||||
| 	) | ||||
| 
 | ||||
| 
 | ||||
| @reversion.register(ignore_duplicates=True) | ||||
| class PrilohaReseni(bm.SeminarModelBase): | ||||
| class PrilohaReseni(SeminarModelBase): | ||||
| 
 | ||||
| 	class Meta: | ||||
| 		db_table = 'seminar_priloha_reseni' | ||||
|  | @ -239,19 +237,3 @@ class Reseni_Resitele(models.Model): | |||
| 	def __str__(self): | ||||
| 		return '{} od {}'.format(self.reseni, self.resitel) | ||||
| 	# NOTE: Poteciální DB HOG bez select_related | ||||
| 
 | ||||
| class ReseniNode(tm.TreeNode): | ||||
| 	class Meta: | ||||
| 		db_table = 'seminar_nodes_otistene_reseni' | ||||
| 		verbose_name = 'Otištěné řešení (Node)' | ||||
| 		verbose_name_plural = 'Otištěná řešení (Node)' | ||||
| 	reseni = models.ForeignKey(Reseni, | ||||
| 							   on_delete=models.PROTECT, | ||||
| 							   verbose_name = 'reseni') | ||||
| 
 | ||||
| 	def aktualizuj_nazev(self): | ||||
| 		self.nazev = "ReseniNode: "+str(self.reseni) | ||||
| 
 | ||||
| 	def getOdkazStr(self): | ||||
| 		return str(self.reseni) | ||||
| 
 | ||||
|  | @ -11,7 +11,7 @@ | |||
|   {% endblock %} | ||||
| </h1> | ||||
| 
 | ||||
| <form enctype="multipart/form-data" action="{% url 'seminar_nahraj_reseni' nadproblem_id %}" method="post" onsubmit="return zkontroluj_prilohy();"> | ||||
| <form enctype="multipart/form-data" action="{% url 'odevzdavatko_nahraj_reseni' nadproblem_id %}" method="post" onsubmit="return zkontroluj_prilohy();"> | ||||
|   {% csrf_token %} | ||||
|   <table class='form'> | ||||
|     <tr> | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ | |||
| 
 | ||||
| <ul> | ||||
|   {% for problem in object_list %} | ||||
|     <li><a href="{% url 'seminar_nahraj_reseni' problem.id %}">{{ problem }}</a></li> | ||||
|     <li><a href="{% url 'odevzdavatko_nahraj_reseni' problem.id %}">{{ problem }}</a></li> | ||||
|   {% empty %} | ||||
|     <li>Nelze nic odevzdávat.</li> | ||||
|   {% endfor %} | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ | |||
|     Vložit řešení | ||||
|   {% endblock %} | ||||
| </h1> | ||||
| <form enctype="multipart/form-data" action="{% url 'seminar_vloz_reseni' %}" method="post" onsubmit="return zkontroluj_prilohy();"> | ||||
| <form enctype="multipart/form-data" action="{% url 'odevzdavatko_vloz_reseni' %}" method="post" onsubmit="return zkontroluj_prilohy();"> | ||||
|   {% csrf_token %} | ||||
| {{form.as_p}} | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,11 +2,11 @@ from django import template | |||
| register = template.Library() | ||||
| 
 | ||||
| from functools import cache | ||||
| import seminar.models as m | ||||
| from odevzdavatko.models import Reseni | ||||
| 
 | ||||
| @register.filter | ||||
| @cache | ||||
| def barva_reseni(r: m.Reseni): | ||||
| def barva_reseni(r: Reseni): | ||||
| 	"""Vrátí nějakou barvu pro daný problém, ve tvaru '#RRGGBB' | ||||
| 
 | ||||
| 	Efektivně hešujeme do barev.""" | ||||
|  |  | |||
|  | @ -2,8 +2,8 @@ from django import template | |||
| register = template.Library() | ||||
| 
 | ||||
| from personalni.utils import normalizuj_jmeno | ||||
| import seminar.models as m # jen kvůli typové anotaci… | ||||
| from personalni.models import Osoba # jen kvůli typové anotaci… | ||||
| 
 | ||||
| @register.filter | ||||
| def jmeno_jako_prefix(o: m.Osoba): | ||||
| def jmeno_jako_prefix(o: Osoba): | ||||
| 	return normalizuj_jmeno(o).replace(' ', '_') | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import datetime | ||||
| import random | ||||
| 
 | ||||
| from seminar.models.odevzdavatko import Reseni, Hodnoceni | ||||
| from odevzdavatko.models import Reseni, Hodnoceni | ||||
| 
 | ||||
| 
 | ||||
| def gen_reseni_ulohy(rnd, cisla, uloha, pocet_resitelu, poradi_cisla, resitele_cisla, resitele): | ||||
|  |  | |||
|  | @ -5,10 +5,10 @@ from various.views.generic import viewMethodSwitch | |||
| from . import views | ||||
| 
 | ||||
| urlpatterns = [ | ||||
| 	path('org/add_solution', org_required(views.VlozReseniView.as_view()), name='seminar_vloz_reseni'), | ||||
| 	path('resitel/nahraj_reseni', resitel_required(views.NahrajReseniRozcestnikTematekView.as_view()), name='seminar_nahraj_reseni'), | ||||
| 	path('resitel/nahraj_reseni/<int:nadproblem_id>/', resitel_required(views.NahrajReseniView.as_view()), name='seminar_nahraj_reseni'), | ||||
| 	path('resitel/odevzdana_reseni/', resitel_or_org_required(views.PrehledOdevzdanychReseni.as_view()), name='seminar_resitel_odevzdana_reseni'), | ||||
| 	path('org/add_solution', org_required(views.VlozReseniView.as_view()), name='odevzdavatko_vloz_reseni'), | ||||
| 	path('resitel/nahraj_reseni', resitel_required(views.NahrajReseniRozcestnikTematekView.as_view()), name='odevzdavatko_nahraj_reseni'), | ||||
| 	path('resitel/nahraj_reseni/<int:nadproblem_id>/', resitel_required(views.NahrajReseniView.as_view()), name='odevzdavatko_nahraj_reseni'), | ||||
| 	path('resitel/odevzdana_reseni/', resitel_or_org_required(views.PrehledOdevzdanychReseni.as_view()), name='odevzdavatko_resitel_odevzdana_reseni'), | ||||
| 
 | ||||
| 	path('org/reseni/', org_required(views.TabulkaOdevzdanychReseniView.as_view()), name='odevzdavatko_tabulka'), | ||||
| 	path('org/reseni/rocnik/<int:rocnik>/', org_required(views.TabulkaOdevzdanychReseniView.as_view()), name='odevzdavatko_tabulka'), | ||||
|  |  | |||
|  | @ -17,10 +17,14 @@ from decimal import Decimal | |||
| from itertools import groupby | ||||
| import logging | ||||
| 
 | ||||
| import seminar.models as m | ||||
| from . import forms as f | ||||
| from .forms import OdevzdavatkoTabulkaFiltrForm as FiltrForm | ||||
| from .models import Hodnoceni, Reseni | ||||
| 
 | ||||
| from personalni.models import Resitel, Osoba, Organizator | ||||
| from tvorba.models import Problem, Deadline, Rocnik | ||||
| from tvorba.utils import resi_v_rocniku | ||||
| from various.models import Nastaveni | ||||
| from various.views.pomocne import formularOKView | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
|  | @ -40,20 +44,20 @@ logger = logging.getLogger(__name__) | |||
| 
 | ||||
| class TabulkaOdevzdanychReseniView(ListView): | ||||
| 	template_name = 'odevzdavatko/tabulka.html' | ||||
| 	model = m.Hodnoceni | ||||
| 	model = Hodnoceni | ||||
| 
 | ||||
| 	def inicializuj_osy_tabulky(self): | ||||
| 		"""Vyrobí prvotní querysety pro sloupce a řádky, tj. seznam všech řešitelů a problémů""" | ||||
| 		# FIXME: jméno metody není vypovídající... | ||||
| 		# NOTE: Tenhle blok nemůže být přímo ve třídě, protože před vyrobením databáze neexistují ty objekty (?). TODO: Otestovat | ||||
| 		# TODO: Prefetches, Select related, ... | ||||
| 		self.resitele = m.Resitel.objects.all() | ||||
| 		self.problemy = m.Problem.objects.all() | ||||
| 		self.reseni = m.Reseni.objects.all() | ||||
| 		self.resitele = Resitel.objects.all() | ||||
| 		self.problemy = Problem.objects.all() | ||||
| 		self.reseni = Reseni.objects.all() | ||||
| 
 | ||||
| 		self.aktualni_rocnik = m.Nastaveni.get_solo().aktualni_rocnik	# .get_solo() vrátí tu jedinou instanci | ||||
| 		self.aktualni_rocnik = Nastaveni.get_solo().aktualni_rocnik	# .get_solo() vrátí tu jedinou instanci | ||||
| 		if 'rocnik' in self.kwargs: | ||||
| 			self.aktualni_rocnik = get_object_or_404(m.Rocnik, rocnik=self.kwargs['rocnik']) | ||||
| 			self.aktualni_rocnik = get_object_or_404(Rocnik, rocnik=self.kwargs['rocnik']) | ||||
| 
 | ||||
| 		form = FiltrForm(self.request.GET, rocnik=self.aktualni_rocnik) | ||||
| 		if form.is_valid(): | ||||
|  | @ -86,14 +90,14 @@ class TabulkaOdevzdanychReseniView(ListView): | |||
| 			self.resitele = self.resitele.filter(rok_maturity__gt=self.aktualni_rocnik.prvni_rok) | ||||
| 
 | ||||
| 		if problemy == FiltrForm.PROBLEMY_MOJE: | ||||
| 			org = m.Organizator.objects.get(osoba__user=self.request.user) | ||||
| 			org = Organizator.objects.get(osoba__user=self.request.user) | ||||
| 			self.problemy = self.problemy.filter( | ||||
| 					Q(autor=org)|Q(garant=org)|Q(opravovatele=org), | ||||
| 					Q(stav=m.Problem.STAV_ZADANY)|Q(stav=m.Problem.STAV_VYRESENY), | ||||
| 					Q(stav=Problem.STAV_ZADANY)|Q(stav=Problem.STAV_VYRESENY), | ||||
| 					) | ||||
| 		elif problemy == FiltrForm.PROBLEMY_LETOSNI: | ||||
| 			self.problemy = self.problemy.filter( | ||||
| 					Q(stav=m.Problem.STAV_ZADANY)|Q(stav=m.Problem.STAV_VYRESENY), | ||||
| 					Q(stav=Problem.STAV_ZADANY)|Q(stav=Problem.STAV_VYRESENY), | ||||
| 					) | ||||
| 			#self.problemy = list(filter(lambda problem: problem.rocnik() == self.aktualni_rocnik, self.problemy)) # DB HOG? # FIXME: některé problémy nemají ročník.... | ||||
| 		# 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. | ||||
|  | @ -121,8 +125,8 @@ class TabulkaOdevzdanychReseniView(ListView): | |||
| 		ctx = super().get_context_data(*args, **kwargs) | ||||
| 		ctx['problemy'] = self.problemy | ||||
| 		ctx['resitele'] = self.resitele | ||||
| 		tabulka: dict[m.Problem, dict[m.Resitel, list[tuple[m.Reseni, m.Hodnoceni]]]] = dict() | ||||
| 		soucty: dict[m.Problem, dict[m.Resitel, Decimal]] = dict() | ||||
| 		tabulka: dict[Problem, dict[Resitel, list[tuple[Reseni, Hodnoceni]]]] = dict() | ||||
| 		soucty: dict[Problem, dict[Resitel, Decimal]] = dict() | ||||
| 
 | ||||
| 		def pridej_reseni(resitel, hodnoceni): | ||||
| 			problem = hodnoceni.problem | ||||
|  | @ -143,11 +147,11 @@ class TabulkaOdevzdanychReseniView(ListView): | |||
| 			for resitel in hodnoceni.reseni.resitele.all(): | ||||
| 				pridej_reseni(resitel, hodnoceni) | ||||
| 
 | ||||
| 		hodnoty: list[list[tuple[Decimal,list[tuple[m.Reseni, m.Hodnoceni]]]]] = [] # Seznam řádků výsledné tabulky podle self.resitele, v každém řádku buňky v pořadí podle self.problemy + jejich součty, v každé buňce seznam řešení k danému řešiteli a problému. | ||||
| 		resitele_do_tabulky: list[m.Resitel] = [] | ||||
| 		hodnoty: list[list[tuple[Decimal,list[tuple[Reseni, Hodnoceni]]]]] = [] # Seznam řádků výsledné tabulky podle self.resitele, v každém řádku buňky v pořadí podle self.problemy + jejich součty, v každé buňce seznam řešení k danému řešiteli a problému. | ||||
| 		resitele_do_tabulky: list[Resitel] = [] | ||||
| 		for resitel in self.resitele: | ||||
| 			dostal_body = False | ||||
| 			resiteluv_radek: list[tuple[Decimal,list[tuple[m.Reseni, m.Hodnoceni]]]] = [] # podle pořadí v self.problemy | ||||
| 			resiteluv_radek: list[tuple[Decimal,list[tuple[Reseni, Hodnoceni]]]] = [] # podle pořadí v self.problemy | ||||
| 			for problem in self.problemy: | ||||
| 				if problem in tabulka and resitel in tabulka[problem]: | ||||
| 					resiteluv_radek.append((soucty[problem][resitel], tabulka[problem][resitel])) | ||||
|  | @ -162,7 +166,7 @@ class TabulkaOdevzdanychReseniView(ListView): | |||
| 		# Pro použití hacku na automatické {{form.media}} v template: | ||||
| 		ctx['form'] = ctx['filtr'] | ||||
| 		# Pro maximum v přesměrovátku ročníků | ||||
| 		ctx['aktualni_rocnik'] = m.Nastaveni.get_solo().aktualni_rocnik | ||||
| 		ctx['aktualni_rocnik'] = Nastaveni.get_solo().aktualni_rocnik | ||||
| 		ctx['barvicky'] = self.barvicky | ||||
| 		if 'rocnik' in self.kwargs: | ||||
| 			ctx['rocnik'] = self.kwargs['rocnik'] | ||||
|  | @ -178,7 +182,7 @@ class ReseniProblemuView(MultipleObjectTemplateResponseMixin, MultipleObjectMixi | |||
| 	Asi už bude zastaralý v okamžiku, kdy se tenhle komentář nasadí na produkci :-) | ||||
| 
 | ||||
| 	V případě, že takové řešení existuje jen jedno, tak na něj přesměruje.""" | ||||
| 	model = m.Reseni | ||||
| 	model = Reseni | ||||
| 	template_name = 'odevzdavatko/seznam.html' | ||||
| 	 | ||||
| 	def get_queryset(self): | ||||
|  | @ -190,8 +194,8 @@ class ReseniProblemuView(MultipleObjectTemplateResponseMixin, MultipleObjectMixi | |||
| 		if problem_id is None: | ||||
| 			raise ValueError("Nemám problém! (To je problém!)") | ||||
| 		 | ||||
| 		resitel = m.Resitel.objects.get(id=resitel_id) | ||||
| 		problem = m.Problem.objects.get(id=problem_id) | ||||
| 		resitel = Resitel.objects.get(id=resitel_id) | ||||
| 		problem = Problem.objects.get(id=problem_id) | ||||
| 		qs = qs.filter( | ||||
| 			problem__in=[problem], | ||||
| 			resitele__in=[resitel], | ||||
|  | @ -221,13 +225,13 @@ class ReseniProblemuView(MultipleObjectTemplateResponseMixin, MultipleObjectMixi | |||
| ## XXX: https://docs.djangoproject.com/en/3.1/topics/class-based-views/mixins/#avoid-anything-more-complex | ||||
| class DetailReseniView(DetailView): | ||||
| 	""" Náhled na řešení. Editace je v :py:class:`EditReseniView`. """ | ||||
| 	model = m.Reseni | ||||
| 	model = Reseni | ||||
| 	template_name = 'odevzdavatko/detail.html' | ||||
| 	 | ||||
| 	def aktualni_hodnoceni(self): | ||||
| 		self.reseni = get_object_or_404(m.Reseni, id=self.kwargs['pk']) | ||||
| 		self.reseni = get_object_or_404(Reseni, id=self.kwargs['pk']) | ||||
| 		result = [] # Slovníky s klíči problem, body, deadline_body -- initial data pro f.OhodnoceniReseniFormSet | ||||
| 		for hodn in m.Hodnoceni.objects.filter(reseni=self.reseni): | ||||
| 		for hodn in Hodnoceni.objects.filter(reseni=self.reseni): | ||||
| 			seznam_atributu = [ | ||||
| 				"problem", | ||||
| 				"body", | ||||
|  | @ -284,7 +288,7 @@ class EditReseniView(DetailReseniView): | |||
| 
 | ||||
| 
 | ||||
| def hodnoceniReseniView(request, pk, *args, **kwargs): | ||||
| 	reseni = get_object_or_404(m.Reseni, pk=pk) | ||||
| 	reseni = get_object_or_404(Reseni, pk=pk) | ||||
| 	success_url = reverse('odevzdavatko_detail_reseni', kwargs={'pk': pk}) | ||||
| 
 | ||||
| 	# FIXME: Použit initial i tady a nebastlit hodnocení tak nízkoúrovňově | ||||
|  | @ -300,7 +304,7 @@ def hodnoceniReseniView(request, pk, *args, **kwargs): | |||
| 		poznamka_form.save() | ||||
| 
 | ||||
| 		# Smažeme všechna dosavadní hodnocení tohoto řešení | ||||
| 		qs = m.Hodnoceni.objects.filter(reseni=reseni) | ||||
| 		qs = Hodnoceni.objects.filter(reseni=reseni) | ||||
| 		logger.info(f"Will delete {qs.count()} objects: {qs}") | ||||
| 		qs.delete() | ||||
| 
 | ||||
|  | @ -311,7 +315,7 @@ def hodnoceniReseniView(request, pk, *args, **kwargs): | |||
| 			del(data_for_hodnoceni["body_celkem"]) | ||||
| 			del(data_for_hodnoceni["body_neprepocitane"]) | ||||
| 			del(data_for_hodnoceni["body_neprepocitane_celkem"]) | ||||
| 			hodnoceni = m.Hodnoceni( | ||||
| 			hodnoceni = Hodnoceni( | ||||
| 					reseni=reseni, | ||||
| 					**form.cleaned_data, | ||||
| 					) | ||||
|  | @ -332,14 +336,14 @@ def hodnoceniReseniView(request, pk, *args, **kwargs): | |||
| 
 | ||||
| 
 | ||||
| class PrehledOdevzdanychReseni(ListView): | ||||
| 	model = m.Hodnoceni | ||||
| 	model = Hodnoceni | ||||
| 	template_name = 'odevzdavatko/prehled_reseni.html' | ||||
| 
 | ||||
| 	def get_queryset(self): | ||||
| 		if not self.request.user.is_authenticated: | ||||
| 			raise RuntimeError("Uživatel měl být přihlášený!") | ||||
| 		# get_or_none, aby neexistence řešitele (např. u orgů) neházela chybu | ||||
| 		resitel = m.Resitel.objects.filter(osoba__user=self.request.user).first() | ||||
| 		resitel = Resitel.objects.filter(osoba__user=self.request.user).first() | ||||
| 		qs = super().get_queryset() | ||||
| 		qs = qs.filter(reseni__resitele__in=[resitel]) | ||||
| 		# Setřídíme podle času doručení řešení, aby se netřídily podle okamžiku vyrobení Hodnocení | ||||
|  | @ -360,13 +364,13 @@ class PrehledOdevzdanychReseni(ListView): | |||
| # Přehled všech řešení kvůli debugování | ||||
| 
 | ||||
| class SeznamReseniView(ListView): | ||||
| 	model = m.Reseni | ||||
| 	model = Reseni | ||||
| 	template_name = 'odevzdavatko/seznam.html' | ||||
| 
 | ||||
| class SeznamAktualnichReseniView(SeznamReseniView): | ||||
| 	def get_queryset(self): | ||||
| 		qs = super().get_queryset() | ||||
| 		akt_rocnik = m.Nastaveni.get_solo().aktualni_rocnik	# .get_solo() vrátí tu jedinou instanci, asi... | ||||
| 		akt_rocnik = Nastaveni.get_solo().aktualni_rocnik	# .get_solo() vrátí tu jedinou instanci, asi... | ||||
| 		resitele = resi_v_rocniku(akt_rocnik) | ||||
| 		qs = qs.filter(resitele__in=resitele)	# FIXME: Najde řešení i ze starých ročníků, která odevzdal alespoň jeden aktuální řešitel | ||||
| 		return qs | ||||
|  | @ -378,7 +382,7 @@ class VlozReseniView(LoginRequiredMixin, FormView): | |||
| 
 | ||||
| 	def form_valid(self, form): | ||||
| 		data = form.cleaned_data | ||||
| 		nove_reseni = m.Reseni.objects.create( | ||||
| 		nove_reseni = Reseni.objects.create( | ||||
| 			cas_doruceni=data['cas_doruceni'], | ||||
| 			forma=data['forma'], | ||||
| 			poznamka=data['poznamka'], | ||||
|  | @ -405,35 +409,35 @@ class VlozReseniView(LoginRequiredMixin, FormView): | |||
| 
 | ||||
| 
 | ||||
| class NahrajReseniRozcestnikTematekView(LoginRequiredMixin, ListView): | ||||
| 	model = m.Problem | ||||
| 	model = Problem | ||||
| 	template_name = 'odevzdavatko/nahraj_reseni_nadproblem.html' | ||||
| 
 | ||||
| 	def get_queryset(self): | ||||
| 		return super().get_queryset().filter(stav=m.Problem.STAV_ZADANY, nadproblem__isnull=True) | ||||
| 		return super().get_queryset().filter(stav=Problem.STAV_ZADANY, nadproblem__isnull=True) | ||||
| 
 | ||||
| 
 | ||||
| class NahrajReseniView(LoginRequiredMixin, CreateView): | ||||
| 	model = m.Reseni | ||||
| 	model = Reseni | ||||
| 	template_name = 'odevzdavatko/nahraj_reseni.html' | ||||
| 	form_class = f.NahrajReseniForm | ||||
| 	nadproblem: m.Problem | ||||
| 	nadproblem: Problem | ||||
| 
 | ||||
| 	def setup(self, request, *args, **kwargs): | ||||
| 		super().setup(request, *args, **kwargs) | ||||
| 		nadproblem_id = self.kwargs["nadproblem_id"] | ||||
| 		self.nadproblem = get_object_or_404(m.Problem, id=nadproblem_id) | ||||
| 		self.nadproblem = get_object_or_404(Problem, id=nadproblem_id) | ||||
| 
 | ||||
| 	def get(self, request, *args, **kwargs): | ||||
| 		# Zaříznutí nezadaných problémů | ||||
| 		if self.nadproblem.stav != m.Problem.STAV_ZADANY: | ||||
| 		if self.nadproblem.stav != Problem.STAV_ZADANY: | ||||
| 			raise PermissionDenied() | ||||
| 
 | ||||
| 
 | ||||
| 		# Zaříznutí starých řešitelů: | ||||
| 		# FIXME: Je to tady dost naprasené, mělo by to asi být jinde… | ||||
| 		osoba = m.Osoba.objects.get(user=self.request.user) | ||||
| 		osoba = Osoba.objects.get(user=self.request.user) | ||||
| 		resitel = osoba.resitel | ||||
| 		if resitel.rok_maturity <= m.Nastaveni.get_solo().aktualni_rocnik.prvni_rok: | ||||
| 		if resitel.rok_maturity <= Nastaveni.get_solo().aktualni_rocnik.prvni_rok: | ||||
| 			return render(request, 'universal.html', { | ||||
| 				'title': 'Nelze odevzdat', | ||||
| 				'error': 'Zdá se, že jsi již odmaturoval/a, a tedy nemůžeš odevzdat do našeho semináře řešení.', | ||||
|  | @ -445,7 +449,7 @@ class NahrajReseniView(LoginRequiredMixin, CreateView): | |||
| 		nadproblem_id = self.nadproblem.id | ||||
| 		return { | ||||
| 			"nadproblem_id": nadproblem_id, | ||||
| 			"problem": [] if self.nadproblem.podproblem.filter(stav=m.Problem.STAV_ZADANY).exists() else nadproblem_id | ||||
| 			"problem": [] if self.nadproblem.podproblem.filter(stav=Problem.STAV_ZADANY).exists() else nadproblem_id | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
|  | @ -457,7 +461,7 @@ class NahrajReseniView(LoginRequiredMixin, CreateView): | |||
| 			data['prilohy'] = f.ReseniSPrilohamiFormSet() | ||||
| 
 | ||||
| 		data["nadproblem_id"] = self.nadproblem.id | ||||
| 		data["nadproblem"] = get_object_or_404(m.Problem, id=self.nadproblem.id) | ||||
| 		data["nadproblem"] = get_object_or_404(Problem, id=self.nadproblem.id) | ||||
| 		return data | ||||
| 
 | ||||
| 	# FIXME prepsat tak, aby form_valid se volalo jen tehdy, kdyz je form i formset validni | ||||
|  | @ -469,17 +473,17 @@ class NahrajReseniView(LoginRequiredMixin, CreateView): | |||
| 			return super().form_invalid(form) | ||||
| 		with transaction.atomic(): | ||||
| 			self.object = form.save() | ||||
| 			self.object.resitele.add(m.Resitel.objects.get(osoba__user = self.request.user)) | ||||
| 			self.object.resitele.add(Resitel.objects.get(osoba__user = self.request.user)) | ||||
| 			self.object.resitele.add(*form.cleaned_data["resitele"]) | ||||
| 			self.object.cas_doruceni = timezone.now() | ||||
| 			self.object.forma = m.Reseni.FORMA_UPLOAD | ||||
| 			self.object.forma = Reseni.FORMA_UPLOAD | ||||
| 			self.object.save() | ||||
| 
 | ||||
| 			prilohy.instance = self.object | ||||
| 			prilohy.save() | ||||
| 
 | ||||
| 		for hodnoceni in self.object.hodnoceni_set.all(): | ||||
| 			hodnoceni.deadline_body = m.Deadline.objects.filter(deadline__gte=self.object.cas_doruceni).first() | ||||
| 			hodnoceni.deadline_body = Deadline.objects.filter(deadline__gte=self.object.cas_doruceni).first() | ||||
| 			hodnoceni.save() | ||||
| 
 | ||||
| 		# Pošleme mail opravovatelům a garantovi | ||||
|  | @ -497,7 +501,7 @@ class NahrajReseniView(LoginRequiredMixin, CreateView): | |||
| 		# FIXME: Víc informativní obsah mailů, možná vč. příloh? | ||||
| 		prijemci = map(lambda it: it.osoba.email, prijemci) | ||||
| 
 | ||||
| 		resitel = m.Osoba.objects.get(user = self.request.user) | ||||
| 		resitel = Osoba.objects.get(user = self.request.user) | ||||
| 
 | ||||
| 		seznam = "problému " + str(problemy[0]) if len(problemy) == 1 else 'následujícím problémům:\n' + ', \n'.join(map(str, problemy)) | ||||
| 		seznam_do_subjectu = "problému " + str(problemy[0]) + ("" if len(problemy) == 1 else f" (a dalším { len(problemy) - 1 })") | ||||
|  | @ -512,5 +516,5 @@ class NahrajReseniView(LoginRequiredMixin, CreateView): | |||
| 		return formularOKView( | ||||
| 			self.request, | ||||
| 			text='Řešení úspěšně odevzdáno', | ||||
| 			dalsi_odkazy=[("Odevzdat další řešení", reverse("seminar_nahraj_reseni"))], | ||||
| 			dalsi_odkazy=[("Odevzdat další řešení", reverse("odevzdavatko_nahraj_reseni"))], | ||||
| 		) | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ from django.contrib import admin | |||
| from django.contrib.auth.models import Group | ||||
| from django_reverse_admin import ReverseModelAdmin | ||||
| from django.contrib.messages import WARNING, ERROR, SUCCESS | ||||
| import seminar.models as m | ||||
| import personalni.models as m | ||||
| from datetime import datetime | ||||
| 
 | ||||
| @admin.action(description="Sjednoť telefony") | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ from django.contrib.auth.forms import PasswordResetForm | |||
| from django.core.exceptions import ObjectDoesNotExist | ||||
| from django.contrib.auth.models import User | ||||
| 
 | ||||
| from seminar.models import Skola, Resitel, Osoba | ||||
| from personalni.models import Skola, Resitel, Osoba | ||||
| 
 | ||||
| from datetime import date | ||||
| import logging | ||||
|  | @ -27,7 +27,7 @@ class TelInput(forms.TextInput): | |||
| 
 | ||||
| class UdajeForm(forms.Form): | ||||
| 	username = None | ||||
| 	err_logger = logging.getLogger('seminar.prihlaska.problem') | ||||
| 	err_logger = logging.getLogger('personalni.prihlaska.problem') | ||||
| 
 | ||||
| 	jmeno = forms.CharField(label='Jméno', max_length=256, required=True) | ||||
| 	prezdivka_resitele = forms.CharField(label='Přezdívka (veřejná)', max_length=256, required=False) | ||||
|  | @ -62,7 +62,7 @@ class UdajeForm(forms.Form): | |||
| 	rok_maturity = forms.IntegerField( | ||||
| 		label='Rok maturity', | ||||
| 		min_value=date.today().year, | ||||
| 		max_value=date.today().year+8, | ||||
| 		max_value=date.today().year+13, | ||||
| 		required=True, | ||||
| 	) | ||||
| 
 | ||||
|  | @ -147,7 +147,7 @@ class PrihlaskaForm(PasswordResetForm, UdajeForm): | |||
| 
 | ||||
| 
 | ||||
| class ProfileEditForm(UdajeForm): | ||||
| 	err_logger = logging.getLogger('seminar.edit.problem') | ||||
| 	err_logger = logging.getLogger('personalni.prihlaska.problem.edit') | ||||
| 	username = forms.CharField( | ||||
| 		label='Přihlašovací jméno', | ||||
| 		max_length=256, | ||||
|  |  | |||
							
								
								
									
										13
									
								
								personalni/migrations/0012_odstrel_odevzdavatka_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								personalni/migrations/0012_odstrel_odevzdavatka_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # Generated by Django 4.2.13 on 2024-10-22 22:17 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0011_osloveni_vsechny_choices'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								personalni/migrations/0013_odstrel_odevzdavatka_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								personalni/migrations/0013_odstrel_odevzdavatka_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.13 on 2024-10-23 21:10 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0012_odstrel_odevzdavatka_pre'), | ||||
|         ('odevzdavatko', '0003_odstrel_odevzdavatka_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										13
									
								
								personalni/migrations/0014_tvorba_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								personalni/migrations/0014_tvorba_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 01:07 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0013_odstrel_odevzdavatka_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								personalni/migrations/0015_tvorba_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								personalni/migrations/0015_tvorba_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 21:35 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0014_tvorba_pre'), | ||||
|         ('tvorba', '0003_tvorba_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										13
									
								
								personalni/migrations/0016_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								personalni/migrations/0016_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # Generated by Django 4.2.16 on 2024-11-02 19:45 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0015_tvorba_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								personalni/migrations/0017_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								personalni/migrations/0017_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.16 on 2024-11-02 20:52 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0016_odstrel_treenode_pre'), | ||||
|         ('treenode', '0003_odstrel_treenode_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
|  | @ -11,7 +11,7 @@ from django_countries.fields import CountryField | |||
| 
 | ||||
| from reversion import revisions as reversion | ||||
| 
 | ||||
| from seminar.models.base import SeminarModelBase | ||||
| from various.models import SeminarModelBase | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
|  | @ -296,7 +296,7 @@ class Resitel(SeminarModelBase): | |||
| 	def vsechny_body(self): | ||||
| 		"Spočítá body odjakživa." | ||||
| 		vsechna_reseni = self.reseni_set.all() | ||||
| 		from seminar.models.odevzdavatko import Hodnoceni | ||||
| 		from odevzdavatko.models import Hodnoceni | ||||
| 		vsechna_hodnoceni = Hodnoceni.objects.filter( | ||||
| 			reseni__in=vsechna_reseni) | ||||
| 		return sum(h.body for h in list(vsechna_hodnoceni) if h.body is not None) | ||||
|  | @ -343,7 +343,7 @@ class Resitel(SeminarModelBase): | |||
| 		#  - body z 25. ročníku a dříve byly shledány dvakrát hodnotnějšími | ||||
| 		#  - proto se započítávají dvojnásobně a byly posunuté hranice titulů | ||||
| 		#  - staré tituly se ale nemají odebrat, pokud řešitel v t.č. minulém (26.) ročníku měl titul, má ho mít pořád. | ||||
| 		from seminar.models.odevzdavatko import Hodnoceni | ||||
| 		from odevzdavatko.models import Hodnoceni | ||||
| 		hodnoceni_do_25_rocniku = Hodnoceni.objects.filter(deadline_body__cislo__rocnik__rocnik__lte=25,reseni__in=self.reseni_set.all()) | ||||
| 		novejsi_hodnoceni = Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()).difference(hodnoceni_do_25_rocniku) | ||||
| 
 | ||||
|  | @ -381,7 +381,7 @@ class Resitel(SeminarModelBase): | |||
| 			else: | ||||
| 				return Titul.akad | ||||
| 
 | ||||
| 		from seminar.models.odevzdavatko import Hodnoceni | ||||
| 		from odevzdavatko.models import Hodnoceni | ||||
| 		hodnoceni_do_26_rocniku = Hodnoceni.objects.filter(deadline_body__cislo__rocnik__rocnik__lte=26,reseni__in=self.reseni_set.all()) | ||||
| 		novejsi_body = body_z_hodnoceni( | ||||
| 			Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()) | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ | |||
| <h2><strong>Tvorba čísla</strong></h2> | ||||
| 
 | ||||
| <ul> | ||||
| 	<li><a href="{% url 'admin:seminar_problem_add' %}"><strong>přidat téma</strong></a></li> | ||||
| 	<li><a href="{% url 'admin:tvorba_problem_add' %}"><strong>přidat téma</strong></a></li> | ||||
| 	<li><strong>korektury</strong> | ||||
| 	<ul> | ||||
| 		<li><a href="{% url 'korektury_list' %}">korekturování</a></li> | ||||
|  | @ -78,7 +78,7 @@ | |||
| 		<li>hlasování o přednáškách</li> | ||||
| 	</ul> | ||||
| 	</li> | ||||
| 	<li><a href="{% url 'seminar_seznam_soustredeni' %}">proběhlá soustředění</a> | ||||
| 	<li><a href="{% url 'soustredeni_seznam' %}">proběhlá soustředění</a> | ||||
| 	<ul> | ||||
| 		<li>vytvoření galerie</li> | ||||
| 		<li>stažení seznamu účastníků</li> | ||||
|  |  | |||
|  | @ -10,9 +10,9 @@ | |||
| </h1> | ||||
| 
 | ||||
| <a href="{% url 'logout' %}">Odhlásit se</a><br> | ||||
| <a href="{% url 'seminar_resitel_edit' %}">Upravit údaje</a><br> | ||||
| <a href="{% url 'seminar_nahraj_reseni' %}">Nahrát řešení</a><br> | ||||
| <a href="{% url 'seminar_resitel_odevzdana_reseni' %}">Již odevzdaná řešení</a><br> | ||||
| <a href="{% url 'personalni_resitel_edit' %}">Upravit údaje</a><br> | ||||
| <a href="{% url 'odevzdavatko_nahraj_reseni' %}">Nahrát řešení</a><br> | ||||
| <a href="{% url 'odevzdavatko_resitel_odevzdana_reseni' %}">Již odevzdaná řešení</a><br> | ||||
| 
 | ||||
| 
 | ||||
| {% endblock %} | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ | |||
| <hr> | ||||
| <p><a href="{% url 'reset_password' %}">Změnit heslo</a></p> | ||||
| 
 | ||||
| <form action="{% url 'seminar_resitel_edit' %}" method="post"> | ||||
| <form action="{% url 'personalni_resitel_edit' %}" method="post"> | ||||
|   {% include "personalni/udaje/udaje.html"%} | ||||
|   <input type="submit" value="Změnit"> | ||||
| </form> | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ | |||
| 
 | ||||
| <p><b>Tučně</b> popsaná pole jsou povinná.</p> | ||||
| 
 | ||||
| <form action="{% url 'seminar_prihlaska' %}" method="post"> | ||||
| <form action="{% url 'personalni_prihlaska' %}" method="post"> | ||||
|   {% include "personalni/udaje/udaje.html" %} | ||||
|   <h4> | ||||
|     GDPR | ||||
|  |  | |||
|  | @ -2,9 +2,9 @@ from django.test import TestCase, RequestFactory | |||
| 
 | ||||
| from django.contrib.auth.models import User, Group | ||||
| from django.contrib.admin.sites import AdminSite | ||||
| from personalni.admin import OsobaAdmin | ||||
| from personalni.admin import OsobaAdmin, udelej_orgem | ||||
| # Tohle bude peklo, až jednou ty modely fakt rozstřelíme… Možná vyrobit various.all_models, které půjdou importovat jako m? :-) | ||||
| import seminar.models as m | ||||
| import personalni.models as m | ||||
| 
 | ||||
| import logging | ||||
| logger = logging.getLogger(__name__) | ||||
|  | @ -42,7 +42,7 @@ class DelaniOrguTest(TestCase): | |||
| 
 | ||||
| 		# Pak orga uděláme… | ||||
| 		qs = m.Osoba.objects.filter(id=self.nova_osoba.id) | ||||
| 		self.admin.udelej_orgem(self.request, qs) | ||||
| 		udelej_orgem(self.admin, self.request, qs) | ||||
| 
 | ||||
| 		# A pak už to org má být. | ||||
| 		self.nova_osoba.refresh_from_db() | ||||
|  | @ -56,7 +56,7 @@ class DelaniOrguTest(TestCase): | |||
| 		self.assertIsNotNone(novy_org.organizuje_od) | ||||
| 
 | ||||
| 	def test_pridani_stareho_orga(self): | ||||
| 		self.admin.udelej_orgem(self.request, m.Osoba.objects.filter(id=self.stary_org.osoba.id)) # Ugly | ||||
| 		udelej_orgem(self.admin, self.request, m.Osoba.objects.filter(id=self.stary_org.osoba.id)) # Ugly | ||||
| 		# Když to spadne, tak jsem se to dozvěděl, takže už nepotřebuju nic kontrolovat. | ||||
| 		# Jestli to funguje správně má řešit jiný test. | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,15 +7,15 @@ urlpatterns = [ | |||
| 	path( | ||||
| 		'org/rozcestnik/', | ||||
| 		org_required(views.OrgoRozcestnikView.as_view()), | ||||
| 		name='seminar_org_rozcestnik' | ||||
| 		name='personalni_org_rozcestnik' | ||||
| 	), | ||||
| 
 | ||||
| 	path('prihlaska/', views.prihlaskaView, name='seminar_prihlaska'), | ||||
| 	path('prihlaska/', views.prihlaskaView, name='personalni_prihlaska'), | ||||
| 
 | ||||
| 	path( | ||||
| 		'resitel/osobni-udaje/', | ||||
| 		login_required(views.resitelEditView), | ||||
| 		name='seminar_resitel_edit' | ||||
| 		name='personalni_resitel_edit' | ||||
| 	), | ||||
| 
 | ||||
| 	# Obecný view na profil -- orgům dá rozcestník, řešitelům jejich stránku | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| import seminar.models as m | ||||
| from various.utils import bez_diakritiky_translate | ||||
| import re | ||||
| 
 | ||||
|  | @ -7,9 +6,10 @@ from django.contrib.auth.decorators import permission_required, user_passes_test | |||
| from django.contrib.auth.models import AnonymousUser | ||||
| from django.db import transaction | ||||
| 
 | ||||
| import seminar.models as m | ||||
| import soustredeni.models | ||||
| 
 | ||||
| from odevzdavatko.models import Reseni_Resitele | ||||
| 
 | ||||
| from .models import Osoba, Organizator, Skola, Resitel, Prijemce | ||||
| 
 | ||||
| 
 | ||||
|  | @ -97,7 +97,7 @@ def merge_resitele(cilovy, zdrojovy): | |||
| 	# Přepojit všechny vazby ze zdrojového na cílového | ||||
| 	print('Přepojuji vazby') | ||||
| 	# Vazby: Škola (hotovo), Řešení_Řešitelé, Konfery_Účastníci, Soustředění_Účastníci, Osoba (vyřeší se později, nejde přepojit) | ||||
| 	ct = m.Reseni_Resitele.objects.filter(resitele=zdrojovy).update(resitele=cilovy) | ||||
| 	ct = Reseni_Resitele.objects.filter(resitele=zdrojovy).update(resitele=cilovy) | ||||
| 	print(f' Přepojeno {ct} řešení') | ||||
| 	ct = soustredeni.models.Konfery_Ucastnici.objects.filter(resitel=zdrojovy).update(resitel=cilovy) | ||||
| 	print(f' Přepojeno {ct} konfer') | ||||
|  |  | |||
|  | @ -16,8 +16,12 @@ from django.db import transaction | |||
| from django.http import HttpResponse | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| import seminar.models as s | ||||
| import seminar.models as m | ||||
| 
 | ||||
| import personalni.models as m | ||||
| from soustredeni.models import Soustredeni | ||||
| from odevzdavatko.models import Hodnoceni | ||||
| from tvorba.models import Clanek, Uloha, Tema | ||||
| from various.models import Nastaveni | ||||
| from .forms import PrihlaskaForm, ProfileEditForm, PoMaturiteProfileEditForm | ||||
| 
 | ||||
| from datetime import date | ||||
|  | @ -91,22 +95,22 @@ class OrgoRozcestnikView(TemplateView): | |||
| 
 | ||||
| 	def get_context_data(self, **kwargs): | ||||
| 		context = super().get_context_data(**kwargs) | ||||
| 		context['posledni_soustredeni'] = s.Soustredeni.objects.order_by('-datum_konce').first() | ||||
| 		nastaveni = s.Nastaveni.objects.first() | ||||
| 		context['posledni_soustredeni'] = Soustredeni.objects.order_by('-datum_konce').first() | ||||
| 		nastaveni = Nastaveni.objects.first() | ||||
| 		aktualni_rocnik = nastaveni.aktualni_rocnik | ||||
| 		context['posledni_cislo_url'] = nastaveni.aktualni_cislo.verejne_url() | ||||
| 		# TODO možná chceme odkazovat na právě rozpracované číslo, a ne to poslední vydané | ||||
| 		# pokud nechceme haluzit kód (= poradi) dalšího čísla, bude asi potřeba jít | ||||
| 		# přes treenody (a dát si přitom pozor na MezicisloNode) | ||||
| 
 | ||||
| 		neobodovana_reseni = s.Hodnoceni.objects.filter(body__isnull=True) | ||||
| 		reseni_mimo_cislo = s.Hodnoceni.objects.filter(deadline_body__isnull=True) | ||||
| 		neobodovana_reseni = Hodnoceni.objects.filter(body__isnull=True) | ||||
| 		reseni_mimo_cislo = Hodnoceni.objects.filter(deadline_body__isnull=True) | ||||
| 		context['pocet_neobodovanych_reseni'] = neobodovana_reseni.count() | ||||
| 		context['pocet_reseni_mimo_cislo'] = reseni_mimo_cislo.count() | ||||
| 
 | ||||
| 		u = self.request.user | ||||
| 		os = s.Osoba.objects.get(user=u) | ||||
| 		organizator = s.Organizator.objects.get(osoba=os) | ||||
| 		os = m.Osoba.objects.get(user=u) | ||||
| 		organizator = m.Organizator.objects.get(osoba=os) | ||||
| 
 | ||||
| 		context['muj_pocet_neobodovanych_reseni'] = neobodovana_reseni.filter(Q(problem__garant=organizator) | Q(problem__autor=organizator) | Q(problem__opravovatele__in=[organizator])).distinct().count() | ||||
| 		context['muj_pocet_reseni_mimo_cislo'] = reseni_mimo_cislo.filter(Q(problem__garant=organizator) | Q(problem__autor=organizator) | Q(problem__opravovatele__in=[organizator])).count() | ||||
|  | @ -116,11 +120,11 @@ class OrgoRozcestnikView(TemplateView): | |||
| 		context["pocty_neopravenych_reseni"] = [(it['problem__nazev'], it['cas'].date) for it in pocty_neopravenych_reseni.all()] | ||||
| 
 | ||||
| 		#FIXME: přidat stav='STAV_ZADANY' | ||||
| 		temata = s.Tema.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), | ||||
| 		temata = Tema.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), | ||||
| 			rocnik=aktualni_rocnik).distinct() | ||||
| 		ulohy = s.Uloha.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), | ||||
| 		ulohy = Uloha.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), | ||||
| 			cislo_zadani__rocnik=aktualni_rocnik).distinct() | ||||
| 		clanky = s.Clanek.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), | ||||
| 		clanky = Clanek.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), | ||||
| 			cislo__rocnik=aktualni_rocnik).distinct() | ||||
| 
 | ||||
| 		context['temata'] = temata | ||||
|  | @ -134,12 +138,12 @@ class OrgoRozcestnikView(TemplateView): | |||
| 
 | ||||
| 
 | ||||
| class ResitelView(LoginRequiredMixin,generic.DetailView): | ||||
| 	model = s.Resitel | ||||
| 	model = m.Resitel | ||||
| 	template_name = 'personalni/profil/resitel.html' | ||||
| 
 | ||||
| 	def get_object(self, queryset=None): | ||||
| 		print(self.request.user) | ||||
| 		return s.Resitel.objects.get(osoba__user=self.request.user) | ||||
| 		return m.Resitel.objects.get(osoba__user=self.request.user) | ||||
| 
 | ||||
| ### Formulare | ||||
| 
 | ||||
|  | @ -157,10 +161,10 @@ def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data): | |||
| 
 | ||||
| @sensitive_post_parameters('jmeno', 'prijmeni', 'email', 'telefon', 'datum_narozeni', 'ulice', 'mesto', 'psc', 'skola') | ||||
| def resitelEditView(request): | ||||
| 	err_logger = logging.getLogger('seminar.prihlaska.problem') | ||||
| 	err_logger = logging.getLogger('personalni.prihlaska.problem') | ||||
| 	## Načtení objektů Osoba a Resitel patřících k aktuálně přihlášenému uživateli | ||||
| 	u = request.user | ||||
| 	osoba_edit = s.Osoba.objects.get(user=u) | ||||
| 	osoba_edit = m.Osoba.objects.get(user=u) | ||||
| 	if hasattr(osoba_edit,'resitel'): | ||||
| 		resitel_edit = osoba_edit.resitel | ||||
| 	else: | ||||
|  | @ -195,7 +199,7 @@ def resitelEditView(request): | |||
| 			## Změny v osobě | ||||
| 			fcd = form.cleaned_data | ||||
| 			form_hash = hash(frozenset(fcd.items())) | ||||
| 			form_logger = logging.getLogger('seminar.prihlaska.form') | ||||
| 			form_logger = logging.getLogger('personalni.prihlaska.form') | ||||
| 			form_logger.info("EDIT:" + str(fcd) + str(form_hash))  # TODO možná logovat jinak | ||||
| 			osoba_edit.jmeno = fcd['jmeno'] | ||||
| 			osoba_edit.prijmeni = fcd['prijmeni'] | ||||
|  | @ -244,9 +248,9 @@ def resitelEditView(request): | |||
| 
 | ||||
| @sensitive_post_parameters('jmeno', 'prijmeni', 'email', 'telefon', 'datum_narozeni', 'ulice', 'mesto', 'psc', 'skola', 'jak_se_dozvedeli') | ||||
| def prihlaskaView(request): | ||||
| 	generic_logger = logging.getLogger('seminar.prihlaska') | ||||
| 	err_logger = logging.getLogger('seminar.prihlaska.problem') | ||||
| 	form_logger = logging.getLogger('seminar.prihlaska.form') | ||||
| 	generic_logger = logging.getLogger('personalni.prihlaska') | ||||
| 	err_logger = logging.getLogger('personalni.prihlaska.problem') | ||||
| 	form_logger = logging.getLogger('personalni.prihlaska.form') | ||||
| 	if request.method == 'POST': | ||||
| 		form = PrihlaskaForm(request.POST) | ||||
| 		# TODO vyresit, co se bude v jakych situacich zobrazovat | ||||
|  | @ -266,7 +270,7 @@ def prihlaskaView(request): | |||
| 				resitel_grp = Group.objects.filter(name__exact='resitel').first() | ||||
| 				u.groups.add(resitel_grp) | ||||
| 
 | ||||
| 				o = s.Osoba( | ||||
| 				o = m.Osoba( | ||||
| 					jmeno = fcd['jmeno'], | ||||
| 					prijmeni = fcd['prijmeni'], | ||||
| 					osloveni = fcd['osloveni'], | ||||
|  | @ -328,7 +332,7 @@ def prihlaskaView(request): | |||
| 				if kolize.count() > 1:	# Jednu z nich jsme právě uložili | ||||
| 					err_logger.warning(f'Zaregistrovala se osoba s kolizním jménem. ID osob: {[o.id for o in kolize]}') | ||||
| 
 | ||||
| 				r = s.Resitel( | ||||
| 				r = m.Resitel( | ||||
| 					prezdivka_resitele=fcd['prezdivka_resitele'] if fcd['prezdivka_resitele'] != "" else None, | ||||
| 					rok_maturity = fcd['rok_maturity'], | ||||
| 					zasilat = fcd['zasilat'], | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ from django.utils.safestring import mark_safe | |||
| from django.utils.html import escape | ||||
| 
 | ||||
| from .models import Prednaska, Seznam, STAV_NAVRH | ||||
| from seminar.models import Soustredeni | ||||
| from soustredeni.models import Soustredeni | ||||
| 
 | ||||
| 
 | ||||
| class Seznam_PrednaskaInline(admin.TabularInline): | ||||
|  |  | |||
|  | @ -6,7 +6,8 @@ from django.db.models import Sum | |||
| from django.forms import Form | ||||
| 
 | ||||
| from prednasky.models import Prednaska, Hlasovani, Seznam, STAV_NAVRH | ||||
| from seminar.models import Soustredeni, Osoba | ||||
| from soustredeni.models import Soustredeni | ||||
| from personalni.models import Osoba | ||||
| 
 | ||||
| def newPrednaska(request): | ||||
| 	# hlasovani se vztahuje k nejnovejsimu soustredeni | ||||
|  |  | |||
|  | @ -1,6 +1,4 @@ | |||
| """ | ||||
| Zde bývalo vše. Teď tu zbývají všechny modely a části webu jako archiv, | ||||
| přehled orgů, aktuální (k aktuálnímu číslu) věci, titulka a jak řešit. | ||||
| 
 | ||||
| Také je tu generování testovacích (lokálních) dat. | ||||
| Zde bývalo vše. Teď tu zbývají migrace. | ||||
| A kód pro `import seminar.models as m` pro ./manage.py shell. | ||||
| """ | ||||
|  | @ -2,10 +2,11 @@ from __future__ import unicode_literals | |||
| 
 | ||||
| from django.db import models, migrations | ||||
| import django_countries.fields | ||||
| import seminar.models | ||||
| import django.utils.timezone | ||||
| from django.conf import settings | ||||
| 
 | ||||
| from odevzdavatko.models import generate_filename | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|  | @ -75,7 +76,7 @@ class Migration(migrations.Migration): | |||
|             fields=[ | ||||
|                 ('id', models.AutoField(serialize=False, primary_key=True)), | ||||
|                 ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvo\u0159eno')), | ||||
|                 ('soubor', models.FileField(upload_to=seminar.models.generate_filename, verbose_name='soubor')), | ||||
|                 ('soubor', models.FileField(upload_to=generate_filename, verbose_name='soubor')), | ||||
|                 ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k p\u0159\xedloze \u0159e\u0161en\xed (plain text), nap\u0159. o p\u016fvodu', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), | ||||
|             ], | ||||
|             options={ | ||||
|  |  | |||
|  | @ -7,9 +7,12 @@ import django.db.models.deletion | |||
| import django.utils.timezone | ||||
| import django_countries.fields | ||||
| import imagekit.models.fields | ||||
| import seminar.models | ||||
| import taggit.managers | ||||
| 
 | ||||
| from soustredeni.models import generate_filename_konfera | ||||
| from odevzdavatko.models import generate_filename | ||||
| from tvorba.models import cislo_pdf_filename, cislo_png_filename | ||||
| 
 | ||||
| from datetime import date | ||||
| from django.db.models import Q | ||||
| from treenode.treelib import get_parent | ||||
|  | @ -962,7 +965,7 @@ class Migration(migrations.Migration): | |||
|             fields=[ | ||||
|                 ('id', models.AutoField(primary_key=True, serialize=False)), | ||||
|                 ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvořeno')), | ||||
|                 ('soubor', models.FileField(upload_to=seminar.models.generate_filename, verbose_name='soubor')), | ||||
|                 ('soubor', models.FileField(upload_to=generate_filename, verbose_name='soubor')), | ||||
|                 ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k příloze řešení (plain text), např. o původu', verbose_name='neveřejná poznámka')), | ||||
|                 ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='prilohy', to='seminar.Reseni', verbose_name='řešení')), | ||||
|             ], | ||||
|  | @ -1284,7 +1287,7 @@ class Migration(migrations.Migration): | |||
|         migrations.AddField( | ||||
|             model_name='cislo', | ||||
|             name='pdf', | ||||
|             field=models.FileField(blank=True, help_text='Pdf čísla, které si mohou řešitelé stáhnout', null=True, upload_to=seminar.models.cislo_pdf_filename, verbose_name='pdf'), | ||||
|             field=models.FileField(blank=True, help_text='Pdf čísla, které si mohou řešitelé stáhnout', null=True, upload_to=cislo_pdf_filename, verbose_name='pdf'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='problem', | ||||
|  | @ -1361,8 +1364,8 @@ class Migration(migrations.Migration): | |||
|                 ('abstrakt', models.TextField(blank=True, help_text='Abstrakt konfery tak, jak byl uveden ve sborníku', verbose_name='abstrakt')), | ||||
|                 ('org_poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka ke konfeře(plain text)', verbose_name='neveřejná poznámka')), | ||||
|                 ('typ_prezentace', models.CharField(choices=[(b'veletrh', 'Veletrh (postery)'), (b'prezentace', 'Prezentace (přednáška)')], default=b'veletrh', max_length=16, verbose_name='typ prezentace')), | ||||
|                 ('prezentace', models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace')), | ||||
|                 ('materialy', models.FileField(help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy')), | ||||
|                 ('prezentace', models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=generate_filename_konfera, verbose_name='prezentace')), | ||||
|                 ('materialy', models.FileField(help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=generate_filename_konfera, verbose_name='materialy')), | ||||
|                 ('organizator', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Organizator', verbose_name='organizátor')), | ||||
|                 ('soustredeni', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Soustredeni', verbose_name='soustředění')), | ||||
|             ], | ||||
|  | @ -1400,12 +1403,12 @@ class Migration(migrations.Migration): | |||
|         migrations.AlterField( | ||||
|             model_name='konfera', | ||||
|             name='materialy', | ||||
|             field=models.FileField(blank=True, help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy'), | ||||
|             field=models.FileField(blank=True, help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=generate_filename_konfera, verbose_name='materialy'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='konfera', | ||||
|             name='prezentace', | ||||
|             field=models.FileField(blank=True, help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace'), | ||||
|             field=models.FileField(blank=True, help_text='Prezentace nebo fotka posteru', upload_to=generate_filename_konfera, verbose_name='prezentace'), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name='konfera', | ||||
|  | @ -2648,12 +2651,12 @@ class Migration(migrations.Migration): | |||
|         migrations.AlterField( | ||||
|             model_name='cislo', | ||||
|             name='pdf', | ||||
|             field=models.FileField(blank=True, help_text='PDF čísla, které si mohou řešitelé stáhnout', null=True, upload_to=seminar.models.cislo_pdf_filename, verbose_name='pdf'), | ||||
|             field=models.FileField(blank=True, help_text='PDF čísla, které si mohou řešitelé stáhnout', null=True, upload_to=cislo_pdf_filename, verbose_name='pdf'), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name='cislo', | ||||
|             name='titulka_nahled', | ||||
|             field=models.ImageField(blank=True, help_text='Obrázek titulní strany, generuje se automaticky', null=True, upload_to=seminar.models.cislo_png_filename, verbose_name='Obrázek titulní strany'), | ||||
|             field=models.ImageField(blank=True, help_text='Obrázek titulní strany, generuje se automaticky', null=True, upload_to=cislo_png_filename, verbose_name='Obrázek titulní strany'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='treenode', | ||||
|  |  | |||
|  | @ -1,10 +1,6 @@ | |||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| import django_countries.fields | ||||
| import seminar.models | ||||
| import django.utils.timezone | ||||
| from django.conf import settings | ||||
| from django.db import migrations | ||||
| 
 | ||||
| CREATE_VIEWS=""" | ||||
| create view seminar_body_za_cislo as | ||||
|  |  | |||
|  | @ -1,10 +1,6 @@ | |||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| import django_countries.fields | ||||
| import seminar.models | ||||
| import django.utils.timezone | ||||
| from django.conf import settings | ||||
| from django.db import migrations | ||||
| 
 | ||||
| CREATE_VIEWS=""" | ||||
| drop view seminar_body_k_cislu; | ||||
|  |  | |||
|  | @ -1,10 +1,6 @@ | |||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| import django_countries.fields | ||||
| import seminar.models | ||||
| import django.utils.timezone | ||||
| from django.conf import settings | ||||
| from django.db import migrations | ||||
| 
 | ||||
| CREATE_VIEWS=""" | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| import seminar.models | ||||
| from tvorba.models import cislo_pdf_filename | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
|  | @ -14,7 +14,7 @@ class Migration(migrations.Migration): | |||
|         migrations.AddField( | ||||
|             model_name='cislo', | ||||
|             name='pdf', | ||||
|             field=models.FileField(help_text='Pdf \u010d\xedsla, kter\xe9 si mohou \u0159e\u0161itel\xe9 st\xe1hnout', upload_to=seminar.models.cislo_pdf_filename, null=True, verbose_name='pdf'), | ||||
|             field=models.FileField(help_text='Pdf \u010d\xedsla, kter\xe9 si mohou \u0159e\u0161itel\xe9 st\xe1hnout', upload_to=cislo_pdf_filename, null=True, verbose_name='pdf'), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|     ] | ||||
|  |  | |||
|  | @ -2,7 +2,8 @@ from __future__ import unicode_literals | |||
| 
 | ||||
| from django.db import models, migrations | ||||
| import django_countries.fields | ||||
| import seminar.models | ||||
| 
 | ||||
| from tvorba.models import cislo_pdf_filename | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
|  | @ -25,7 +26,7 @@ class Migration(migrations.Migration): | |||
|         migrations.AlterField( | ||||
|             model_name='cislo', | ||||
|             name='pdf', | ||||
|             field=models.FileField(help_text='Pdf \u010d\xedsla, kter\xe9 si mohou \u0159e\u0161itel\xe9 st\xe1hnout', upload_to=seminar.models.cislo_pdf_filename, null=True, verbose_name='pdf', blank=True), | ||||
|             field=models.FileField(help_text='Pdf \u010d\xedsla, kter\xe9 si mohou \u0159e\u0161itel\xe9 st\xe1hnout', upload_to=cislo_pdf_filename, null=True, verbose_name='pdf', blank=True), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|  |  | |||
|  | @ -2,7 +2,8 @@ from __future__ import unicode_literals | |||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| import seminar.models | ||||
| 
 | ||||
| from soustredeni.models import generate_filename_konfera | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
|  | @ -21,8 +22,8 @@ class Migration(migrations.Migration): | |||
|                 ('abstrakt', models.TextField(help_text='Abstrakt konfery tak, jak byl uveden ve sborn\xedku', verbose_name='abstrakt', blank=True)), | ||||
|                 ('org_poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka ke konfe\u0159e(plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), | ||||
|                 ('typ_prezentace', models.CharField(default=b'veletrh', max_length=16, verbose_name='typ prezentace', choices=[(b'veletrh', 'Veletrh (postery)'), (b'prezentace', 'Prezentace (p\u0159edn\xe1\u0161ka)')])), | ||||
|                 ('prezentace', models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace')), | ||||
|                 ('materialy', models.FileField(help_text='Dal\u0161\xed materi\xe1ly ke konfe\u0159e zabalen\xe9 do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy')), | ||||
|                 ('prezentace', models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=generate_filename_konfera, verbose_name='prezentace')), | ||||
|                 ('materialy', models.FileField(help_text='Dal\u0161\xed materi\xe1ly ke konfe\u0159e zabalen\xe9 do jednoho souboru', upload_to=generate_filename_konfera, verbose_name='materialy')), | ||||
|                 ('organizator', models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='organiz\xe1tor', to='seminar.Organizator', null=True)), | ||||
|             ], | ||||
|             options={ | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ from __future__ import unicode_literals | |||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| import seminar.models | ||||
| from soustredeni.models import generate_filename_konfera | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
|  | @ -15,12 +15,12 @@ class Migration(migrations.Migration): | |||
|         migrations.AlterField( | ||||
|             model_name='konfera', | ||||
|             name='materialy', | ||||
|             field=models.FileField(help_text='Dal\u0161\xed materi\xe1ly ke konfe\u0159e zabalen\xe9 do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy', blank=True), | ||||
|             field=models.FileField(help_text='Dal\u0161\xed materi\xe1ly ke konfe\u0159e zabalen\xe9 do jednoho souboru', upload_to=generate_filename_konfera, verbose_name='materialy', blank=True), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='konfera', | ||||
|             name='prezentace', | ||||
|             field=models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace', blank=True), | ||||
|             field=models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=generate_filename_konfera, verbose_name='prezentace', blank=True), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='konfera', | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| # Generated by Django 2.2.9 on 2020-04-08 20:21 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import seminar.models | ||||
| 
 | ||||
| from tvorba.models import cislo_pdf_filename | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
|  | @ -19,6 +20,6 @@ class Migration(migrations.Migration): | |||
|         migrations.AlterField( | ||||
|             model_name='cislo', | ||||
|             name='pdf', | ||||
|             field=models.FileField(blank=True, help_text='PDF čísla, které si mohou řešitelé stáhnout', null=True, upload_to=seminar.models.cislo_pdf_filename, verbose_name='pdf'), | ||||
|             field=models.FileField(blank=True, help_text='PDF čísla, které si mohou řešitelé stáhnout', null=True, upload_to=cislo_pdf_filename, verbose_name='pdf'), | ||||
|         ), | ||||
|     ] | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| # Generated by Django 2.2.12 on 2020-05-06 17:51 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import seminar.models | ||||
| from tvorba.models import cislo_png_filename | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
|  | @ -14,6 +14,6 @@ class Migration(migrations.Migration): | |||
|         migrations.AlterField( | ||||
|             model_name='cislo', | ||||
|             name='titulka_nahled', | ||||
|             field=models.ImageField(blank=True, help_text='Obrázek titulní strany, generuje se automaticky', null=True, upload_to=seminar.models.cislo_png_filename, verbose_name='Obrázek titulní strany'), | ||||
|             field=models.ImageField(blank=True, help_text='Obrázek titulní strany, generuje se automaticky', null=True, upload_to=cislo_png_filename, verbose_name='Obrázek titulní strany'), | ||||
|         ), | ||||
|     ] | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| # Generated by Django 2.2.24 on 2021-11-29 22:54 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import seminar.models.tvorba | ||||
| import various.models | ||||
| from tvorba.models import cislo_pdf_filename | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
|  | @ -14,6 +15,6 @@ class Migration(migrations.Migration): | |||
|         migrations.AlterField( | ||||
|             model_name='cislo', | ||||
|             name='pdf', | ||||
|             field=models.FileField(blank=True, help_text='PDF čísla, které si mohou řešitelé stáhnout', null=True, storage=seminar.models.tvorba.OverwriteStorage(), upload_to=seminar.models.tvorba.cislo_pdf_filename, verbose_name='pdf'), | ||||
|             field=models.FileField(blank=True, help_text='PDF čísla, které si mohou řešitelé stáhnout', null=True, storage=various.models.OverwriteStorage(), upload_to=cislo_pdf_filename, verbose_name='pdf'), | ||||
|         ), | ||||
|     ] | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ from django.db import migrations, models | |||
| import django.db.models.deletion | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| import seminar.models as m | ||||
| from tvorba.models import Deadline as mDeadline | ||||
| 
 | ||||
| 
 | ||||
| def vytvor_deadliny(apps, schema_editor): | ||||
|  | @ -16,7 +16,7 @@ def vytvor_deadliny(apps, schema_editor): | |||
|         if cislo.rocnik.rocnik < 26: | ||||
|             Deadline.objects.create( | ||||
|                 cislo=cislo, | ||||
|                 typ=m.Deadline.TYP_CISLA, | ||||
|                 typ=mDeadline.TYP_CISLA, | ||||
|                 deadline=timezone.make_aware(datetime.datetime.combine(datetime.date(1994 + cislo.rocnik.rocnik, 6, int(cislo.poradi[0])), datetime.time.min)), | ||||
|                 verejna_vysledkovka=cislo.verejna_vysledkovka, | ||||
|             ) | ||||
|  | @ -33,24 +33,24 @@ def vytvor_deadliny(apps, schema_editor): | |||
|         if cislo.datum_deadline_soustredeni and cislo.datum_deadline_soustredeni == cislo.datum_preddeadline: | ||||
|             vytvor_deadline( | ||||
|                 date=cislo.datum_deadline_soustredeni, | ||||
|                 typ=m.Deadline.TYP_PRVNI_A_SOUS | ||||
|                 typ=mDeadline.TYP_PRVNI_A_SOUS | ||||
|             ) | ||||
|         else: | ||||
|             if cislo.datum_deadline_soustredeni: | ||||
|                 vytvor_deadline( | ||||
|                     date=cislo.datum_deadline_soustredeni, | ||||
|                     typ=m.Deadline.TYP_SOUS | ||||
|                     typ=mDeadline.TYP_SOUS | ||||
|                 ) | ||||
|             if cislo.datum_preddeadline: | ||||
|                 vytvor_deadline( | ||||
|                     date=cislo.datum_preddeadline, | ||||
|                     typ=m.Deadline.TYP_PRVNI | ||||
|                     typ=mDeadline.TYP_PRVNI | ||||
|                 ) | ||||
| 
 | ||||
|         if cislo.datum_deadline: | ||||
|             vytvor_deadline( | ||||
|                 date=cislo.datum_deadline, | ||||
|                 typ=m.Deadline.TYP_CISLA | ||||
|                 typ=mDeadline.TYP_CISLA | ||||
|             ) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| # Generated by Django 3.2.15 on 2022-10-09 10:14 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| from seminar.models import Deadline | ||||
| from tvorba.models import Deadline | ||||
| 
 | ||||
| 
 | ||||
| def vrat_deadliny(apps, schema_editor): | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| # Generated by Django 3.2.15 on 2022-10-09 11:04 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| from seminar.models import Deadline | ||||
| from tvorba.models import Deadline | ||||
| 
 | ||||
| 
 | ||||
| def vrat_verejnost(apps, schema_editor): | ||||
|  |  | |||
							
								
								
									
										14
									
								
								seminar/migrations/0131_odstrel_odevzdavatka_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								seminar/migrations/0131_odstrel_odevzdavatka_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.13 on 2024-10-22 22:17 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0130_clanek_strana'), | ||||
|         ('personalni', '0012_odstrel_odevzdavatka_pre'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										29
									
								
								seminar/migrations/0132_unmanage_odevzdavatko.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								seminar/migrations/0132_unmanage_odevzdavatko.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| # Generated by Django 4.2.13 on 2024-10-22 22:31 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0131_odstrel_odevzdavatka_pre'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterModelOptions( | ||||
|             name='hodnoceni', | ||||
|             options={'managed': False, 'verbose_name': 'Hodnocení', 'verbose_name_plural': 'Hodnocení'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='prilohareseni', | ||||
|             options={'managed': False, 'ordering': ['reseni', 'vytvoreno'], 'verbose_name': 'Příloha řešení', 'verbose_name_plural': 'Přílohy řešení'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='reseni', | ||||
|             options={'managed': False, 'ordering': ['-cas_doruceni'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='reseni_resitele', | ||||
|             options={'managed': False, 'ordering': ['reseni', 'resitele'], 'verbose_name': 'Řešení řešitelů', 'verbose_name_plural': 'Řešení řešitelů'}, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										20
									
								
								seminar/migrations/0133_relink_odevzdavatko.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								seminar/migrations/0133_relink_odevzdavatko.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| # Generated by Django 4.2.13 on 2024-10-23 19:53 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('odevzdavatko', '0001_create'), | ||||
|         ('seminar', '0132_unmanage_odevzdavatko'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterField( | ||||
|             model_name='reseninode', | ||||
|             name='reseni', | ||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='odevzdavatko.reseni', verbose_name='reseni'), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										50
									
								
								seminar/migrations/0134_delete_odevzdavatko.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								seminar/migrations/0134_delete_odevzdavatko.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | |||
| # Generated by Django 4.2.13 on 2024-10-23 19:56 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0133_relink_odevzdavatko'), | ||||
|         ('odevzdavatko', '0001_create'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.RemoveField( | ||||
|             model_name='prilohareseni', | ||||
|             name='reseni', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='reseni', | ||||
|             name='problem', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='reseni', | ||||
|             name='resitele', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='reseni', | ||||
|             name='text_cely', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='reseni_resitele', | ||||
|             name='reseni', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='reseni_resitele', | ||||
|             name='resitele', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Hodnoceni', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='PrilohaReseni', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Reseni', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Reseni_Resitele', | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								seminar/migrations/0135_odstrel_odevzdavatka_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								seminar/migrations/0135_odstrel_odevzdavatka_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.13 on 2024-10-23 21:10 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0134_delete_odevzdavatko'), | ||||
|         ('odevzdavatko', '0003_odstrel_odevzdavatka_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										21
									
								
								seminar/migrations/0136_tvorba_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								seminar/migrations/0136_tvorba_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 01:06 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0135_odstrel_odevzdavatka_post'), | ||||
|         ('odevzdavatko', '0004_tvorba_pre'), | ||||
|         ('various', '0004_tvorba_pre'), | ||||
|         ('soustredeni', '0004_tvorba_pre'), | ||||
|         ('personalni', '0014_tvorba_pre'), | ||||
|         # Polymorphic: | ||||
|         ('contenttypes', '0002_remove_content_type_name'), | ||||
|         # Taggit | ||||
|         ('taggit', '0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										59
									
								
								seminar/migrations/0137_tvorba_unmanage.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								seminar/migrations/0137_tvorba_unmanage.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 11:19 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0136_tvorba_pre'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name='Problemy_Opravovatele', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(primary_key=True, serialize=False)), | ||||
|             ], | ||||
|             options={ | ||||
|                 'db_table': 'seminar_problemy_opravovatele', | ||||
|                 'managed': False, | ||||
|             }, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='cislo', | ||||
|             options={'managed': False, 'ordering': ['-rocnik__rocnik', '-poradi'], 'verbose_name': 'Číslo', 'verbose_name_plural': 'Čísla'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='clanek', | ||||
|             options={'managed': False, 'verbose_name': 'Článek', 'verbose_name_plural': 'Články'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='deadline', | ||||
|             options={'managed': False, 'ordering': ['deadline'], 'verbose_name': 'Deadline', 'verbose_name_plural': 'Deadliny'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='pohadka', | ||||
|             options={'managed': False, 'ordering': ['vytvoreno'], 'verbose_name': 'Pohádka', 'verbose_name_plural': 'Pohádky'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='problem', | ||||
|             options={'managed': False, 'ordering': ['nazev'], 'verbose_name': 'Problém', 'verbose_name_plural': 'Problémy'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='rocnik', | ||||
|             options={'managed': False, 'ordering': ['-rocnik'], 'verbose_name': 'Ročník', 'verbose_name_plural': 'Ročníky'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='tema', | ||||
|             options={'managed': False, 'verbose_name': 'Téma', 'verbose_name_plural': 'Témata'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='uloha', | ||||
|             options={'managed': False, 'verbose_name': 'Úloha', 'verbose_name_plural': 'Úlohy'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='zmrazenavysledkovka', | ||||
|             options={'managed': False, 'verbose_name': 'Zmražená výsledkovka', 'verbose_name_plural': 'Zmražené výsledkovky'}, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										150
									
								
								seminar/migrations/0138_tvorba_delete.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								seminar/migrations/0138_tvorba_delete.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,150 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 14:03 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('tvorba', '0001_tvorba_create'), | ||||
|         ('seminar', '0137_tvorba_unmanage'), | ||||
|         ('odevzdavatko', '0005_tvorba_relink'), | ||||
|         ('soustredeni', '0009_tvorba_relink5'), | ||||
|         ('various', '0005_tvorba_relink'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.RemoveField( | ||||
|             model_name='cislo', | ||||
|             name='rocnik', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='clanek', | ||||
|             name='cislo', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='clanek', | ||||
|             name='problem_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='deadline', | ||||
|             name='cislo', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='pohadka', | ||||
|             name='autor', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='problem', | ||||
|             name='autor', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='problem', | ||||
|             name='garant', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='problem', | ||||
|             name='nadproblem', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='problem', | ||||
|             name='opravovatele', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='problem', | ||||
|             name='polymorphic_ctype', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='problem', | ||||
|             name='zamereni', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Problemy_Opravovatele', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='tema', | ||||
|             name='problem_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='tema', | ||||
|             name='rocnik', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='uloha', | ||||
|             name='cislo_deadline', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='uloha', | ||||
|             name='cislo_reseni', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='uloha', | ||||
|             name='cislo_zadani', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='uloha', | ||||
|             name='problem_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='zmrazenavysledkovka', | ||||
|             name='deadline', | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='cislonode', | ||||
|             name='cislo', | ||||
|             field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='tvorba.cislo', verbose_name='číslo'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='pohadkanode', | ||||
|             name='pohadka', | ||||
|             field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='tvorba.pohadka', verbose_name='pohádka'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='rocniknode', | ||||
|             name='rocnik', | ||||
|             field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='tvorba.rocnik', verbose_name='ročník'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='temavcislenode', | ||||
|             name='tema', | ||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tvorba.tema', verbose_name='téma v čísle'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='ulohavzoraknode', | ||||
|             name='uloha', | ||||
|             field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='tvorba.uloha', verbose_name='úloha'), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='ulohazadaninode', | ||||
|             name='uloha', | ||||
|             field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='tvorba.uloha', verbose_name='úloha'), | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Cislo', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Clanek', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Deadline', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Pohadka', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Problem', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Rocnik', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Tema', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Uloha', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='ZmrazenaVysledkovka', | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								seminar/migrations/0139_tvorba_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								seminar/migrations/0139_tvorba_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 21:35 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0138_tvorba_delete'), | ||||
|         ('tvorba', '0003_tvorba_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										17
									
								
								seminar/migrations/0140_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								seminar/migrations/0140_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| # Generated by Django 4.2.16 on 2024-11-02 19:45 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0139_tvorba_post'), | ||||
|         ('odevzdavatko', '0007_odstrel_treenode_pre'), | ||||
|         ('personalni', '0016_odstrel_treenode_pre'), | ||||
|         ('tvorba', '0004_odstrel_treenode_pre'), | ||||
|         ('contenttypes', '0002_remove_content_type_name'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										69
									
								
								seminar/migrations/0141_odstrel_treenode_unmanage.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								seminar/migrations/0141_odstrel_treenode_unmanage.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,69 @@ | |||
| # Generated by Django 4.2.16 on 2024-11-02 19:56 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0140_odstrel_treenode_pre'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterModelOptions( | ||||
|             name='castnode', | ||||
|             options={'managed': False, 'verbose_name': 'Část (Node)', 'verbose_name_plural': 'Části (Node)'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='cislonode', | ||||
|             options={'managed': False, 'verbose_name': 'Číslo (Node)', 'verbose_name_plural': 'Čísla (Node)'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='mezicislonode', | ||||
|             options={'managed': False, 'verbose_name': 'Mezičíslo (Node)', 'verbose_name_plural': 'Mezičísla (Node)'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='obrazek', | ||||
|             options={'managed': False, 'verbose_name': 'obrázek', 'verbose_name_plural': 'obrázky'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='orgtextnode', | ||||
|             options={'managed': False, 'verbose_name': 'Organizátorský článek (Node)', 'verbose_name_plural': 'Organizátorské články (Node)'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='pohadkanode', | ||||
|             options={'managed': False, 'verbose_name': 'Pohádka (Node)', 'verbose_name_plural': 'Pohádky (Node)'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='reseninode', | ||||
|             options={'managed': False, 'verbose_name': 'Otištěné řešení (Node)', 'verbose_name_plural': 'Otištěná řešení (Node)'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='rocniknode', | ||||
|             options={'managed': False, 'verbose_name': 'Ročník (Node)', 'verbose_name_plural': 'Ročníky (Node)'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='temavcislenode', | ||||
|             options={'managed': False, 'verbose_name': 'Téma v čísle (Node)', 'verbose_name_plural': 'Témata v čísle (Node)'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='text', | ||||
|             options={'managed': False, 'verbose_name': 'text', 'verbose_name_plural': 'texty'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='textnode', | ||||
|             options={'managed': False, 'verbose_name': 'Text (Node)', 'verbose_name_plural': 'Text (Node)'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='treenode', | ||||
|             options={'managed': False, 'verbose_name': 'TreeNode', 'verbose_name_plural': 'TreeNody'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='ulohavzoraknode', | ||||
|             options={'managed': False, 'verbose_name': 'Vzorák úlohy (Node)', 'verbose_name_plural': 'Vzoráky úloh (Node)'}, | ||||
|         ), | ||||
|         migrations.AlterModelOptions( | ||||
|             name='ulohazadaninode', | ||||
|             options={'managed': False, 'verbose_name': 'Zadání úlohy (Node)', 'verbose_name_plural': 'Zadání úloh (Node)'}, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										153
									
								
								seminar/migrations/0142_odstrel_treenode_delete.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								seminar/migrations/0142_odstrel_treenode_delete.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,153 @@ | |||
| # Generated by Django 4.2.16 on 2024-11-02 20:47 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0141_odstrel_treenode_unmanage'), | ||||
|         ('odevzdavatko', '0008_odstrel_treenode_relink'), | ||||
|         ('treenode', '0001_odstrel_treenode_create'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.RemoveField( | ||||
|             model_name='cislonode', | ||||
|             name='cislo', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='cislonode', | ||||
|             name='treenode_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='mezicislonode', | ||||
|             name='treenode_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='obrazek', | ||||
|             name='text', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='orgtextnode', | ||||
|             name='organizator', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='orgtextnode', | ||||
|             name='treenode_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='pohadkanode', | ||||
|             name='pohadka', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='pohadkanode', | ||||
|             name='treenode_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='reseninode', | ||||
|             name='reseni', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='reseninode', | ||||
|             name='treenode_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='rocniknode', | ||||
|             name='rocnik', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='rocniknode', | ||||
|             name='treenode_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='temavcislenode', | ||||
|             name='tema', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='temavcislenode', | ||||
|             name='treenode_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='textnode', | ||||
|             name='text', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='textnode', | ||||
|             name='treenode_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='treenode', | ||||
|             name='first_child', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='treenode', | ||||
|             name='polymorphic_ctype', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='treenode', | ||||
|             name='root', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='treenode', | ||||
|             name='succ', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='ulohavzoraknode', | ||||
|             name='treenode_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='ulohavzoraknode', | ||||
|             name='uloha', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='ulohazadaninode', | ||||
|             name='treenode_ptr', | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='ulohazadaninode', | ||||
|             name='uloha', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='CastNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='CisloNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='MezicisloNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Obrazek', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='OrgTextNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='PohadkaNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='ReseniNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='RocnikNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='TemaVCisleNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='Text', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='TextNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='TreeNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='UlohaVzorakNode', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='UlohaZadaniNode', | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								seminar/migrations/0143_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								seminar/migrations/0143_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.16 on 2024-11-02 20:52 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0142_odstrel_treenode_delete'), | ||||
|         ('treenode', '0003_odstrel_treenode_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										43
									
								
								seminar/migrations/0144_post_odstrel_vseho.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								seminar/migrations/0144_post_odstrel_vseho.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| # Generated by Django 4.2.16 on 2024-11-03 01:55 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| # Myšlenka: Tahle migrace o sobě prohlašuje, že závisí na všem, co se do téhle chvíle stalo. To má dva důsledky: | ||||
| # 1. V okamžiku, kdy tahle migrace proběhne, tak už máme model ve stavu který očekáváme. IOW slouží jako bariéra, za kterou nemůžou přetéct úpravy ostatních aplikací (hlavně těch našich) | ||||
| # 2. Zároveň ale tvrdíme, že k tomu, aby tahle migrace proběhla, potřebujeme (potenciálně relativně staré) verze cizích aplikací, což způsobí uspořádání opačným směrem: DB změny cizích aplikací naopak proběhnou až po této migraci | ||||
| #     Vzhledem k tomu, že by i naše předchozí aplikace měly záviset na těchto změnách, tak tím efektivně vynucujeme zachování stavu pro ty mezilehlé migrace, které možná (chybou) nedokumentovaně spoléhají na to, jak vypadají cizí aplikace. | ||||
| # Plán do budoucna: Jakmile tahle migrace proběhne na všech myslitelných databázích, můžeme její předchůdce prostě smazat a nahradit nějakou výrazně snazší sadou migrací, která jen vygeneruje správně tabulky a závislosti podle aktuálního modelu. | ||||
| #  - To se ve skutečnosti vesměs už stalo, v odstřelených aplikacích jsou modely stejně všechny „nové s daty spadlými z nebe“. Je moc pozdě v noci, ale myslím si, že prostě bude stačit smazat závislosti na migracích v `seminar`i a celou aplikaci `seminar` zrušit. (Největší problém je to při nasazování DB z nuly např. u generování testdat…) | ||||
| # Je otázka, jestli tahle migrace nemá bydlet ve `various` či jinde, aby se dala smazat celá složka `seminar`. | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('admin', '0003_logentry_add_action_flag_choices'), | ||||
|         ('auth', '0012_alter_user_first_name_max_length'), | ||||
|         ('authtoken', '0004_alter_tokenproxy_options'), | ||||
|         ('contenttypes', '0002_remove_content_type_name'), | ||||
|         ('flatpages', '0001_initial'), | ||||
|         ('galerie', '0013_post_split_soustredeni'), | ||||
|         ('header_fotky', '0001_initial'), | ||||
|         ('korektury', '0024_vic_orgu_k_pdf'), | ||||
|         ('novinky', '0004_alter_novinky_id'), | ||||
|         ('odevzdavatko', '0009_odstrel_treenode_post'), | ||||
|         ('personalni', '0017_odstrel_treenode_post'), | ||||
|         ('prednasky', '0018_post_split_soustredeni'), | ||||
|         ('reversion', '0002_add_index_on_version_for_content_type_and_db'), | ||||
|         ('seminar', '0143_odstrel_treenode_post'), | ||||
|         ('sessions', '0001_initial'), | ||||
|         ('sifrovacka', '0006_personalni_post_migrate'), | ||||
|         ('sites', '0002_alter_domain_unique'), | ||||
|         ('sitetree', '0002_alter_treeitem_parent_alter_treeitem_tree'), | ||||
|         ('soustredeni', '0010_tvorba_post'), | ||||
|         ('taggit', '0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx'), | ||||
|         ('treenode', '0003_odstrel_treenode_post'), | ||||
|         ('tvorba', '0005_odstrel_treenode_post'), | ||||
|         ('various', '0006_tvorba_post'), | ||||
|         ('vyroci', '0001_initial'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										15
									
								
								seminar/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								seminar/models.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| # Tento soubor slouží pouze pro shell a podobné. Nikde neimportovat v kódu! | ||||
| 
 | ||||
| print("Naimportoval jsi `seminar.models`. Pevně věřím, že to nebylo nikde v kódu. Díky.") | ||||
| 
 | ||||
| from galerie.models import * | ||||
| from header_fotky.models import * | ||||
| from korektury.models import * | ||||
| from novinky.models import * | ||||
| from odevzdavatko.models import * | ||||
| from personalni.models import * | ||||
| from prednasky.models import * | ||||
| from soustredeni.models import * | ||||
| from treenode.models import * | ||||
| from tvorba.models import * | ||||
| from various.models import * | ||||
|  | @ -1,13 +0,0 @@ | |||
| from .tvorba import * | ||||
| from .odevzdavatko import * | ||||
| from .base import * | ||||
| from .pomocne import * | ||||
| from .treenode import * | ||||
| 
 | ||||
| from various.models import Nastaveni | ||||
| from personalni.models import Organizator, Resitel, Skola, Prijemce, Osoba | ||||
| from soustredeni.models import Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Konfera, Konfery_Ucastnici | ||||
| from novinky.models import Novinky | ||||
| 
 | ||||
| # Kvůli migr. 0041 | ||||
| from soustredeni.models import generate_filename_konfera | ||||
|  | @ -1,22 +0,0 @@ | |||
| from django.urls import reverse | ||||
| from django.db import models | ||||
| 
 | ||||
| 
 | ||||
| class SeminarModelBase(models.Model): | ||||
| 
 | ||||
| 	class Meta: | ||||
| 		abstract = True | ||||
| 
 | ||||
| 	def verejne(self): | ||||
| 		return False | ||||
| 
 | ||||
| 	# def get_absolute_url(self): | ||||
| 	# 	return "https://" + str(get_current_site(None)) + self.verejne_url() | ||||
| 
 | ||||
| 	def admin_url(self): | ||||
| 		model_name = self.__class__.__name__.lower() | ||||
| 		return reverse('admin:seminar_{}_change'.format(model_name), args=(self.id, )) | ||||
| 
 | ||||
| # def verejne_url(self): | ||||
| # 	return None | ||||
| 
 | ||||
|  | @ -1,69 +0,0 @@ | |||
| import logging | ||||
| import os | ||||
| from django.db import models | ||||
| 
 | ||||
| from .base import SeminarModelBase | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
| 
 | ||||
| class Text(SeminarModelBase): | ||||
| 	class Meta: | ||||
| 		db_table = 'seminar_texty' | ||||
| 		verbose_name = 'text' | ||||
| 		verbose_name_plural = 'texty' | ||||
| 
 | ||||
| 	na_web = models.TextField( | ||||
| 		'text na web', blank=True, | ||||
| 		help_text='Text ke zveřejnění na webu') | ||||
| 
 | ||||
| 	do_cisla = models.TextField( | ||||
| 		'text do čísla', blank=True, | ||||
| 		help_text='Text ke zveřejnění v čísle') | ||||
| 
 | ||||
| 	# má OneToOneField s: | ||||
| 	# Reseni (je u něj jako reseni_cele) | ||||
| 
 | ||||
| 	# obrázky mají návaznost opačným směrem (vazba z druhé strany) | ||||
| 
 | ||||
| 	def save(self, *args, **kwargs): | ||||
| 		super().save(*args, **kwargs) | ||||
| 		# *Node.save() aktualizuje název *Nodu. | ||||
| 		for tn in self.textnode_set.all(): | ||||
| 			tn.save() | ||||
| 
 | ||||
| 	def __str__(self): | ||||
| 		return str(self.na_web)[:20] | ||||
| 
 | ||||
| 
 | ||||
| class Obrazek(SeminarModelBase): | ||||
| 	class Meta: | ||||
| 		db_table = 'seminar_obrazky' | ||||
| 		verbose_name = 'obrázek' | ||||
| 		verbose_name_plural = 'obrázky' | ||||
| 
 | ||||
| 	# Interní ID | ||||
| 	id = models.AutoField(primary_key=True) | ||||
| 
 | ||||
| 	na_web = models.ImageField( | ||||
| 		'obrázek na web', upload_to='obrazky/%Y/%m/%d/', | ||||
| 		null=True, blank=True) | ||||
| 
 | ||||
| 	text = models.ForeignKey( | ||||
| 		Text, verbose_name='text', | ||||
| 		help_text='text, ve kterém se obrázek vyskytuje', | ||||
| 		null=False, blank=False, on_delete=models.CASCADE) | ||||
| 
 | ||||
| 	do_cisla_barevny = models.FileField( | ||||
| 		'barevný obrázek do čísla', | ||||
| 		help_text='Barevná verze obrázku do čísla', | ||||
| 		upload_to='obrazky/%Y/%m/%d/', blank=True, null=True) | ||||
| 
 | ||||
| 	do_cisla_cernobily = models.FileField( | ||||
| 		'černobílý obrázek do čísla', | ||||
| 		help_text='Černobílá verze obrázku do čísla', | ||||
| 		upload_to='obrazky/%Y/%m/%d/', blank=True, null=True) | ||||
| 
 | ||||
| 	# TODO placement hint - chci ho tady / pred textem / za textem | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										13
									
								
								soustredeni/migrations/0004_tvorba_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								soustredeni/migrations/0004_tvorba_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 01:07 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('soustredeni', '0003_post_split_soustredeni'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										28
									
								
								soustredeni/migrations/0005_tvorba_relink.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								soustredeni/migrations/0005_tvorba_relink.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 13:18 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('tvorba', '0001_tvorba_create'), | ||||
|         ('soustredeni', '0004_tvorba_pre'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         ## Konferu zmigrujeme jinak, kvůli <https://code.djangoproject.com/ticket/23521> jí nejde přepsat někde ve stavu `bases`. | ||||
|         ## Proto si ji unmanagujeme a vyrobíme celou znovu, to by nemělo vadit (zvlášť když t.č. v DB žádná instance Konfery není). | ||||
|         ## (Šlo by `SeparateStateAndData`, což v principu děláme taky ale ty migrace jsou lehce čitelnější a o poznání konzistentnější.) | ||||
|         #migrations.AlterField( | ||||
|         #    model_name='konfera', | ||||
|         #    name='problem_ptr', | ||||
|         #    field=models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='tvorba.problem'), | ||||
|         #), | ||||
|         migrations.AlterField( | ||||
|             model_name='soustredeni', | ||||
|             name='rocnik', | ||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='soustredeni', to='tvorba.rocnik', verbose_name='ročník'), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										17
									
								
								soustredeni/migrations/0006_tvorba_relink2.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								soustredeni/migrations/0006_tvorba_relink2.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 19:37 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('soustredeni', '0005_tvorba_relink'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterModelOptions( | ||||
|             name='konfera', | ||||
|             options={'managed': False, 'verbose_name': 'Konfera', 'verbose_name_plural': 'Konfery'}, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										15
									
								
								soustredeni/migrations/0007_tvorba_relink3.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								soustredeni/migrations/0007_tvorba_relink3.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 19:38 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('soustredeni', '0006_tvorba_relink2'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.DeleteModel( | ||||
|             name='Konfera', | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										34
									
								
								soustredeni/migrations/0008_tvorba_relink4.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								soustredeni/migrations/0008_tvorba_relink4.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 19:45 | ||||
| 
 | ||||
| from django.db import migrations,models | ||||
| import django.db.models.deletion | ||||
| import soustredeni.models | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('soustredeni', '0007_tvorba_relink3'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name='Konfera', | ||||
|             fields=[ | ||||
|                 ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='tvorba.problem')), | ||||
|                 ('anotace', models.TextField(blank=True, help_text='Popis, o čem bude konfera.', verbose_name='anotace')), | ||||
|                 ('abstrakt', models.TextField(blank=True, help_text='Abstrakt konfery tak, jak byl uveden ve sborníku', verbose_name='abstrakt')), | ||||
|                 ('typ_prezentace', models.CharField(choices=[('veletrh', 'Veletrh (postery)'), ('prezentace', 'Prezentace (přednáška)')], default='veletrh', max_length=16, verbose_name='typ prezentace')), | ||||
|                 ('prezentace', models.FileField(blank=True, help_text='Prezentace nebo fotka posteru', upload_to=soustredeni.models.generate_filename_konfera, verbose_name='prezentace')), | ||||
|                 ('materialy', models.FileField(blank=True, help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=soustredeni.models.generate_filename_konfera, verbose_name='materialy')), | ||||
|                 ('soustredeni', models.ForeignKey(to='soustredeni.soustredeni', verbose_name='soustředění', on_delete=models.SET_NULL, null=True, related_name='konfery')), | ||||
|                 ('ucastnici', models.ManyToManyField(help_text='Seznam účastníků konfery', through='soustredeni.Konfery_Ucastnici', to='personalni.resitel', verbose_name='účastníci konfery')), | ||||
|             ], | ||||
|             options={ | ||||
|                 'verbose_name': 'Konfera', | ||||
|                 'verbose_name_plural': 'Konfery', | ||||
|                 'db_table': 'seminar_konfera', | ||||
|                 'managed': False, | ||||
|             }, | ||||
|             bases=('tvorba.problem',), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										17
									
								
								soustredeni/migrations/0009_tvorba_relink5.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								soustredeni/migrations/0009_tvorba_relink5.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 20:03 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('soustredeni', '0008_tvorba_relink4'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterModelOptions( | ||||
|             name='konfera', | ||||
|             options={'verbose_name': 'Konfera', 'verbose_name_plural': 'Konfery'}, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								soustredeni/migrations/0010_tvorba_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								soustredeni/migrations/0010_tvorba_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.16 on 2024-10-30 21:35 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('soustredeni', '0009_tvorba_relink5'), | ||||
|         ('tvorba', '0003_tvorba_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue