Dokumentace aplikace prednasky
				
					
				
			This commit is contained in:
		
							parent
							
								
									34f0dffd79
								
							
						
					
					
						commit
						5125525238
					
				
					 5 changed files with 106 additions and 20 deletions
				
			
		|  | @ -0,0 +1,3 @@ | ||||||
|  | """ | ||||||
|  | Aplikace umožňující orgům vypisovat si přednášky a účastníkům o nich hlasovat. | ||||||
|  | """ | ||||||
|  | @ -9,6 +9,10 @@ from soustredeni.models import Soustredeni | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Seznam_PrednaskaInline(admin.TabularInline): | class Seznam_PrednaskaInline(admin.TabularInline): | ||||||
|  | 	""" | ||||||
|  | 		Pomůcka pro :py:class:`prednasky.admin.SeznamAdmin` zobrazující hezky :py:class:`Přednášky <prednasky.models.Prednaska>` | ||||||
|  | 		v adminu :py:class:`Seznamu <prednasky.models.Seznam>`. | ||||||
|  | 	""" | ||||||
| 	model = Prednaska.seznamy.through | 	model = Prednaska.seznamy.through | ||||||
| 	extra = 0 | 	extra = 0 | ||||||
| 
 | 
 | ||||||
|  | @ -55,6 +59,7 @@ class Seznam_PrednaskaInline(admin.TabularInline): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class SeznamAdmin(VersionAdmin): | class SeznamAdmin(VersionAdmin): | ||||||
|  | 	""" Admin pro :py:class:`Seznam <prednasky.models.Seznam>` """ | ||||||
| 	list_display = ['soustredeni', 'stav'] | 	list_display = ['soustredeni', 'stav'] | ||||||
| 	inlines = [Seznam_PrednaskaInline] | 	inlines = [Seznam_PrednaskaInline] | ||||||
| 
 | 
 | ||||||
|  | @ -62,6 +67,7 @@ admin.site.register(Seznam, SeznamAdmin) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class PrednaskaAdmin(VersionAdmin): | class PrednaskaAdmin(VersionAdmin): | ||||||
|  | 	""" Admin pro :py:class:`Přednášku <prednasky.models.Prednaska> """ | ||||||
| 	list_display = ['nazev', 'org', 'obor'] | 	list_display = ['nazev', 'org', 'obor'] | ||||||
| 	list_filter = ['org', 'obor'] | 	list_filter = ['org', 'obor'] | ||||||
| 	search_fields = ['nazev'] | 	search_fields = ['nazev'] | ||||||
|  | @ -70,6 +76,7 @@ class PrednaskaAdmin(VersionAdmin): | ||||||
| 	actions = ['move_to_soustredeni'] | 	actions = ['move_to_soustredeni'] | ||||||
| 
 | 
 | ||||||
| 	def move_to_soustredeni(self, request, queryset): | 	def move_to_soustredeni(self, request, queryset): | ||||||
|  | 		""" Přidá dané přednášky do seznamu, o kterém se právě hlasuje """ | ||||||
| 		sous = Soustredeni.objects.first() | 		sous = Soustredeni.objects.first() | ||||||
| 		seznam = Seznam.objects.filter(soustredeni=sous, stav=Seznam.Stav.NAVRH) | 		seznam = Seznam.objects.filter(soustredeni=sous, stav=Seznam.Stav.NAVRH) | ||||||
| 		if len(seznam) == 0: | 		if len(seznam) == 0: | ||||||
|  | @ -100,6 +107,10 @@ admin.site.register(Prednaska, PrednaskaAdmin) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ZnalostAdmin(PrednaskaAdmin): # Trochu hack, ať nemusím vypisovat všechno znovu | class ZnalostAdmin(PrednaskaAdmin): # Trochu hack, ať nemusím vypisovat všechno znovu | ||||||
|  | 	""" | ||||||
|  | 		Admin pro :py:class:`Znalost <prednasky.models.Znalost> | ||||||
|  | 		TODO předělat, aby nedědila z :py:class:`prednasky.admin.PrednaskaAdmin`, ale společné věci byly zvlášť | ||||||
|  | 	""" | ||||||
| 	list_display = ("__str__",) | 	list_display = ("__str__",) | ||||||
| 	list_filter = () | 	list_filter = () | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,13 +3,29 @@ from django import forms | ||||||
| from .models import Hlasovani, HlasovaniOZnalostech | from .models import Hlasovani, HlasovaniOZnalostech | ||||||
| 
 | 
 | ||||||
| class HlasovaniPrednaskaForm(forms.Form): | class HlasovaniPrednaskaForm(forms.Form): | ||||||
|  | 	""" :py:class:`Formulář <django.forms.Form>` pro pro :py:class:`Hlasování <prednasky.models.Hlasovani>` o jedné :py:class:`Přednášce <prednasky.models.Prednaska>` | ||||||
|  | 	(neobsahuje téměř nic, většina se musí doplnit jiným způsobem) | ||||||
|  | 	""" | ||||||
|  | 
 | ||||||
|  | 	#: ID :py:class:`Přednášky <prednasky.models.Prednaska>`, o které se hlasuje | ||||||
| 	prednaska_id = forms.IntegerField(widget=forms.HiddenInput) | 	prednaska_id = forms.IntegerField(widget=forms.HiddenInput) | ||||||
|  | 	#: :py:class:`Hodnocení (Body) <prednasky.models.Hlasovani.Body>` této přednášky | ||||||
| 	body = forms.ChoiceField(label=False, widget=forms.RadioSelect, choices=Hlasovani.Body.choices, initial=Hlasovani.Body.JEDNO) | 	body = forms.ChoiceField(label=False, widget=forms.RadioSelect, choices=Hlasovani.Body.choices, initial=Hlasovani.Body.JEDNO) | ||||||
| 
 | 
 | ||||||
|  | #: Množina formulářů (:py:class:`formset <django.forms.formsets.BaseFormSet>` :py:class:`HlasovaniPrednaskaFormů <prednasky.forms.HlasovaniPrednaskaForm>`) | ||||||
|  | #: pro :py:class:`Hlasování <prednasky.models.Hlasovani>` o množině :py:class:`Přednášek <prednasky.models.Prednaska>` | ||||||
| HlasovaniPrednaskaFormSet = forms.formset_factory(HlasovaniPrednaskaForm, extra=0) | HlasovaniPrednaskaFormSet = forms.formset_factory(HlasovaniPrednaskaForm, extra=0) | ||||||
| 
 | 
 | ||||||
| class HlasovaniZnalostiForm(forms.Form): | class HlasovaniZnalostiForm(forms.Form): | ||||||
|  | 	""" :py:class:`Formulář <django.forms.Form>` pro pro :py:class:`HlasováníOZnalostech <prednasky.models.HlasovaniOZnalostech>` o jedné :py:class:`Znalosti <prednasky.models.Znalost>` | ||||||
|  | 	(neobsahuje téměř nic, většina se musí doplnit jiným způsobem) | ||||||
|  | 	""" | ||||||
|  | 
 | ||||||
|  | 	#: ID :py:class:`Znalosti <prednasky.models.Znalost>`, o které hlasujeme | ||||||
| 	znalost_id = forms.IntegerField(widget=forms.HiddenInput) | 	znalost_id = forms.IntegerField(widget=forms.HiddenInput) | ||||||
|  | 	#: :py:class:`Odpověď <prednasky.models.HlasovaniOZnalostech.Odpoved>` na tuto znalost | ||||||
| 	odpoved = forms.ChoiceField(label=False, widget=forms.RadioSelect, choices=HlasovaniOZnalostech.Odpoved.choices) | 	odpoved = forms.ChoiceField(label=False, widget=forms.RadioSelect, choices=HlasovaniOZnalostech.Odpoved.choices) | ||||||
| 
 | 
 | ||||||
|  | #: Množina formulářů (:py:class:`formset <django.forms.formsets.BaseFormSet>` :py:class:`HlasovaniZnalostiFormů <prednasky.forms.HlasovaniZnalostiForm>`) | ||||||
|  | #: pro :py:class:`HlasováníOZnalostech <prednasky.models.HlasovaniOZnalostech>` o množině :py:class:`Znalostí <prednasky.models.Znalost>` | ||||||
| HlasovaniZnalostiFormSet = forms.formset_factory(HlasovaniZnalostiForm, extra=0) | HlasovaniZnalostiFormSet = forms.formset_factory(HlasovaniZnalostiForm, extra=0) | ||||||
|  |  | ||||||
|  | @ -5,6 +5,12 @@ from personalni.models import Organizator, Osoba | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Seznam(models.Model): | class Seznam(models.Model): | ||||||
|  | 	""" | ||||||
|  | 		Spojuje :py:class:`Přednášky <prednasky.models.Prednaska>` | ||||||
|  | 		se :py:class:`Soustředěními <soustredeni.models.Soustredeni>`, | ||||||
|  | 		kde by mohly zaznít, nebo zazní/zazněly. | ||||||
|  | 	""" | ||||||
|  | 
 | ||||||
| 	class Meta: | 	class Meta: | ||||||
| 		db_table = "prednasky_seznam" | 		db_table = "prednasky_seznam" | ||||||
| 		verbose_name = "Seznam přednášek" | 		verbose_name = "Seznam přednášek" | ||||||
|  | @ -12,18 +18,23 @@ class Seznam(models.Model): | ||||||
| 		ordering = ["soustredeni", "stav"] | 		ordering = ["soustredeni", "stav"] | ||||||
| 
 | 
 | ||||||
| 	class Stav(models.IntegerChoices): | 	class Stav(models.IntegerChoices): | ||||||
|  | 		""" Stav seznamu přednášek (NAVRH se používá k hlasování viz :py:func:`daný view <prednasky.views.newPrednaska>`). """ | ||||||
| 		NAVRH = 1, "Návrh" | 		NAVRH = 1, "Návrh" | ||||||
| 		BUDE = 2, "Bude" | 		BUDE = 2, "Bude" | ||||||
| 
 | 
 | ||||||
| 	id = models.AutoField(primary_key=True) | 	id = models.AutoField(primary_key=True) | ||||||
| 	soustredeni = models.ForeignKey(Soustredeni, null=True, default=None, on_delete=models.PROTECT) | 	soustredeni = models.ForeignKey(Soustredeni, null=True, default=None, on_delete=models.PROTECT) | ||||||
| 	stav = models.IntegerField("Stav", choices=Stav.choices, default=Stav.NAVRH) | 	stav = models.IntegerField("Stav", choices=Stav.choices, default=Stav.NAVRH) #: :py:class:`Stav <prednasky.models.Seznam.Stav>` Seznamu | ||||||
| 
 | 
 | ||||||
| 	def __str__(self): | 	def __str__(self): | ||||||
| 		return f"Seznam {'návrhů ' if self.stav == Seznam.Stav.NAVRH else ''}přednášek na {self.soustredeni}" | 		return f"Seznam {'návrhů ' if self.stav == Seznam.Stav.NAVRH else ''}přednášek na {self.soustredeni}" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Prednaska(models.Model): | class Prednaska(models.Model): | ||||||
|  | 	""" | ||||||
|  | 		Reprezentuje přednášku, kterou si org může vypsat a účastník o ní hlasovat. | ||||||
|  | 		(Viz :py:class:`Hlasování <prednasky.models.Hlasovani>`.) | ||||||
|  | 	""" | ||||||
| 	class Meta: | 	class Meta: | ||||||
| 		db_table = "prednasky_prednaska" | 		db_table = "prednasky_prednaska" | ||||||
| 		verbose_name = "Přednáška" | 		verbose_name = "Přednáška" | ||||||
|  | @ -40,7 +51,7 @@ class Prednaska(models.Model): | ||||||
| 	org = models.ForeignKey(Organizator, on_delete=models.PROTECT) | 	org = models.ForeignKey(Organizator, on_delete=models.PROTECT) | ||||||
| 	popis = models.TextField("Popis pro orgy", null=True, blank=True, help_text="Neveřejný popis pro ostatní orgy") | 	popis = models.TextField("Popis pro orgy", null=True, blank=True, help_text="Neveřejný popis pro ostatní orgy") | ||||||
| 	anotace = models.TextField("Anotace", null=True, blank=True, help_text="Veřejná anotace v hlasování") | 	anotace = models.TextField("Anotace", null=True, blank=True, help_text="Veřejná anotace v hlasování") | ||||||
| 	obtiznost = models.IntegerField("Obtížnost", choices=Obtiznost.choices) | 	obtiznost = models.IntegerField("Obtížnost", choices=Obtiznost.choices) #: :py:class:`Obtížnost <prednasky.models.Prednaska.Obtiznost>` Přednášky | ||||||
| 	obor = models.CharField("Obor", max_length=5, help_text="Podmnožina MFIOB") | 	obor = models.CharField("Obor", max_length=5, help_text="Podmnožina MFIOB") | ||||||
| 	klicova = models.CharField("Klíčová slova", max_length=200, null=True, blank=True) | 	klicova = models.CharField("Klíčová slova", max_length=200, null=True, blank=True) | ||||||
| 	seznamy = models.ManyToManyField(Seznam) | 	seznamy = models.ManyToManyField(Seznam) | ||||||
|  | @ -50,6 +61,11 @@ class Prednaska(models.Model): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Hlasovani(models.Model): | class Hlasovani(models.Model): | ||||||
|  | 	""" | ||||||
|  | 		Reprezentuje hlasování jednoho účastníka | ||||||
|  | 		o jedné :py:class:`Přednášce <prednasky.models.Prednaska>` | ||||||
|  | 		v jednom :py:class:`Seznamu <prednasky.models.Seznam>` (účastníkův pohled se totiž mezi sousy změnit) | ||||||
|  | 	""" | ||||||
| 	class Meta: | 	class Meta: | ||||||
| 		db_table = "prednasky_hlasovani" | 		db_table = "prednasky_hlasovani" | ||||||
| 		verbose_name = "Hlasování" | 		verbose_name = "Hlasování" | ||||||
|  | @ -57,17 +73,20 @@ class Hlasovani(models.Model): | ||||||
| 		ordering = ["ucastnik", "prednaska"] | 		ordering = ["ucastnik", "prednaska"] | ||||||
| 
 | 
 | ||||||
| 	class Body(models.IntegerChoices): | 	class Body(models.IntegerChoices): | ||||||
|  | 		""" Ohodnocení přednášky v daném Hlasování (větší číslo = víc chci) """ | ||||||
| 		NECHCI = -1, "rozhodně nechci" | 		NECHCI = -1, "rozhodně nechci" | ||||||
| 		JEDNO = 0, "je mi to jedno" | 		JEDNO = 0, "je mi to jedno" | ||||||
| 		CHCI = 1, "rozhodně chci" | 		CHCI = 1, "rozhodně chci" | ||||||
| 
 | 
 | ||||||
| 	id = models.AutoField(primary_key=True) | 	id = models.AutoField(primary_key=True) | ||||||
| 	prednaska = models.ForeignKey(Prednaska, on_delete=models.CASCADE) | 	prednaska = models.ForeignKey(Prednaska, on_delete=models.CASCADE) | ||||||
|  | 	#: Příslušné hlasování: :py:class:`Body <prednasky.models.Hlasovani.Body>` | ||||||
| 	body = models.IntegerField("Body", default=Body.JEDNO, choices=Body.choices) | 	body = models.IntegerField("Body", default=Body.JEDNO, choices=Body.choices) | ||||||
| 
 | 
 | ||||||
| 	# (přechod z jména na objekt Osoby nějak kape na tom, | 	#: Účastník, který hlasoval. Pouze string: | ||||||
| 	# že všechna předchozí hlasování zde mají náhodný string…) | 	#: *(přechod z jména na objekt Osoby nějak kape na tom, | ||||||
| 	# TODO Změnit to na Osobu | 	#: že všechna předchozí hlasování zde mají náhodný string…) | ||||||
|  | 	#: TODO Změnit to na Osobu* | ||||||
| 	ucastnik = models.CharField("Účastník", max_length=100) | 	ucastnik = models.CharField("Účastník", max_length=100) | ||||||
| 	seznam = models.ForeignKey(Seznam, null=True, on_delete=models.SET_NULL) | 	seznam = models.ForeignKey(Seznam, null=True, on_delete=models.SET_NULL) | ||||||
| 
 | 
 | ||||||
|  | @ -76,6 +95,10 @@ class Hlasovani(models.Model): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Znalost(models.Model): | class Znalost(models.Model): | ||||||
|  | 	""" | ||||||
|  | 		Reprezentuje znalost, na kterou se můžeme účastníka ptát (nechat je hlasovat). | ||||||
|  | 		(Viz :py:class:`HlasováníOZnalostech <prednasky.models.HlasovaniOZnalostech>`.) | ||||||
|  | 	""" | ||||||
| 	class Meta: | 	class Meta: | ||||||
| 		db_table = "prednasky_znalost" | 		db_table = "prednasky_znalost" | ||||||
| 		verbose_name = "Znalost k přednáškám" | 		verbose_name = "Znalost k přednáškám" | ||||||
|  | @ -90,12 +113,17 @@ class Znalost(models.Model): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class HlasovaniOZnalostech(models.Model): | class HlasovaniOZnalostech(models.Model): | ||||||
|  | 	""" | ||||||
|  | 		Reprezentuje hlasování jednoho účastníka | ||||||
|  | 		o jedné :py:class:`Znalosti <prednasky.models.Znalost>` | ||||||
|  | 		v jednom :py:class:`Seznamu <prednasky.models.Seznam>` (účastníkův pohled se totiž mezi sousy změnit) | ||||||
|  | 	""" | ||||||
| 	class Odpoved(models.IntegerChoices): | 	class Odpoved(models.IntegerChoices): | ||||||
| 		UMIM = -1, "Tohle celkem umím" | 		UMIM = -1, "Tohle celkem umím" | ||||||
| 		CIRCA = 0, "Už jsem o tom slyšel, ale neřekl bychm, že to úplně umím" | 		CIRCA = 0, "Už jsem o tom slyšel, ale neřekl bychm, že to úplně umím" | ||||||
| 		NEUMIM = 1, "Tohle vůbec neznám" | 		NEUMIM = 1, "Tohle vůbec neznám" | ||||||
| 
 | 
 | ||||||
| 	odpoved = models.CharField(u"odpověď", max_length=16, choices=Odpoved.choices, blank=False, null=False) | 	odpoved = models.CharField(u"odpověď", max_length=16, choices=Odpoved.choices, blank=False, null=False) #: :py:class:`Odpověď <prednasky.models.Prednaska.Odpoved>` na HlasováníOZnalostech | ||||||
| 	znalost = models.ForeignKey(Znalost, on_delete=models.CASCADE, blank=False, null=False) | 	znalost = models.ForeignKey(Znalost, on_delete=models.CASCADE, blank=False, null=False) | ||||||
| 	ucastnik = models.ForeignKey(Osoba, on_delete=models.CASCADE, blank=False, null=False) | 	ucastnik = models.ForeignKey(Osoba, on_delete=models.CASCADE, blank=False, null=False) | ||||||
| 	seznam = models.ForeignKey(Seznam, on_delete=models.SET_NULL, blank=True, null=True) | 	seznam = models.ForeignKey(Seznam, on_delete=models.SET_NULL, blank=True, null=True) | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ import csv | ||||||
| import http | import http | ||||||
| import logging | import logging | ||||||
| 
 | 
 | ||||||
| from django.http import HttpResponse | from django.http import HttpResponse, HttpRequest | ||||||
| from django.shortcuts import render, get_object_or_404 | from django.shortcuts import render, get_object_or_404 | ||||||
| from django.views import generic | from django.views import generic | ||||||
| from django.shortcuts import HttpResponseRedirect | from django.shortcuts import HttpResponseRedirect | ||||||
|  | @ -22,7 +22,14 @@ ZNALOSTI_PREFIX = "znalosti" | ||||||
| 
 | 
 | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
| 
 | 
 | ||||||
| def newPrednaska(request): | def newPrednaska(request: HttpRequest) -> HttpResponse: | ||||||
|  | 	""" | ||||||
|  | 		View zobrazující a ukládající účastnické hlasování | ||||||
|  | 		(:py:class:`Hlasování <prednasky.models.Hlasovani>` | ||||||
|  | 		a :py:class:`HlasováníOZnalostech <prednasky.models.HlasovaniOZnalostech>`) | ||||||
|  | 		o :py:class:`Přednáškách <prednasky.models.Prednaska>` | ||||||
|  | 		a :py:class:`Znalostech <prednasky.models.Znalost>` | ||||||
|  | 	""" | ||||||
| 	# hlasovani se vztahuje k nejnovejsimu soustredeni | 	# hlasovani se vztahuje k nejnovejsimu soustredeni | ||||||
| 	sous = Nastaveni.get_solo().aktualni_sous | 	sous = Nastaveni.get_solo().aktualni_sous | ||||||
| 	seznam = Seznam.objects.filter(soustredeni = sous, stav=Seznam.Stav.NAVRH).first() | 	seznam = Seznam.objects.filter(soustredeni = sous, stav=Seznam.Stav.NAVRH).first() | ||||||
|  | @ -35,12 +42,14 @@ def newPrednaska(request): | ||||||
| 	osoba = Osoba.objects.filter(user=request.user).first() | 	osoba = Osoba.objects.filter(user=request.user).first() | ||||||
| 	ucastnik = osoba.plne_jmeno() + ' ' + str(osoba.id) # id, kvůli kolizi jmen | 	ucastnik = osoba.plne_jmeno() + ' ' + str(osoba.id) # id, kvůli kolizi jmen | ||||||
| 
 | 
 | ||||||
| 	if request.method == 'POST': | 	if request.method == 'POST': # Když to byl POST, tak ukládáme. | ||||||
|  | 		# Načteme data do formsetů | ||||||
| 		form_set_prednasky = HlasovaniPrednaskaFormSet(request.POST, prefix=PREDNASKY_PREFIX) | 		form_set_prednasky = HlasovaniPrednaskaFormSet(request.POST, prefix=PREDNASKY_PREFIX) | ||||||
| 		form_set_znalosti = HlasovaniZnalostiFormSet(request.POST, prefix=ZNALOSTI_PREFIX) | 		form_set_znalosti = HlasovaniZnalostiFormSet(request.POST, prefix=ZNALOSTI_PREFIX) | ||||||
| 
 | 
 | ||||||
| 		if form_set_prednasky.is_valid() and form_set_znalosti.is_valid(): | 		if form_set_prednasky.is_valid() and form_set_znalosti.is_valid(): | ||||||
| 			with transaction.atomic(): | 			with transaction.atomic(): | ||||||
|  | 				# Místo updatování data prostě smažeme a vytvoříme nová | ||||||
| 				seznam.hlasovani_set.filter(ucastnik=ucastnik).delete() | 				seznam.hlasovani_set.filter(ucastnik=ucastnik).delete() | ||||||
| 				seznam.hlasovanioznalostech_set.filter(ucastnik=osoba).delete() | 				seznam.hlasovanioznalostech_set.filter(ucastnik=osoba).delete() | ||||||
| 
 | 
 | ||||||
|  | @ -73,17 +82,19 @@ def newPrednaska(request): | ||||||
| 					) | 					) | ||||||
| 
 | 
 | ||||||
| 			return HttpResponseRedirect('./hotovo') | 			return HttpResponseRedirect('./hotovo') | ||||||
| 		else: | 
 | ||||||
|  | 		else: # Pokud je nějaký formset nevalidní, vracíme je k přepracování | ||||||
| 			prednasky = seznam.prednaska_set.all() | 			prednasky = seznam.prednaska_set.all() | ||||||
| 			znalosti = seznam.znalost_set.all() | 			znalosti = seznam.znalost_set.all() | ||||||
| 			# Spadnout, pokud nesedí přednáška/znalost s formulářem. (Nějak se mi to nepovedlo.) | 			# FIXME Spadnout, pokud nesedí přednáška/znalost s formulářem. (Nějak se mi to nepovedlo.) | ||||||
|  | 			# Může se totiž stát, že se mezitím změnily přednášky (nějaká byla přidána/odebrána) | ||||||
| 
 | 
 | ||||||
| 	else: | 	else: # Když to nebyl POST, tak inicializujeme (pokud už o přednášce/znalosti účastník hlasoval, předvyplníme mu to). | ||||||
| 		def odpoved_prednasky(p): | 		def odpoved_prednasky(p: Prednaska) -> Hlasovani.Body: | ||||||
| 			hlasovani = p.hlasovani_set.filter(ucastnik=ucastnik).first() | 			hlasovani = p.hlasovani_set.filter(ucastnik=ucastnik).first() | ||||||
| 			return hlasovani.body if hlasovani else Hlasovani.Body.JEDNO | 			return hlasovani.body if hlasovani else Hlasovani.Body.JEDNO | ||||||
| 
 | 
 | ||||||
| 		def odpoved_znalosti(z): | 		def odpoved_znalosti(z: Znalost) -> Znalost.Odpoved: | ||||||
| 			hlasovani = z.hlasovanioznalostech_set.filter(ucastnik=osoba).first() | 			hlasovani = z.hlasovanioznalostech_set.filter(ucastnik=osoba).first() | ||||||
| 			return hlasovani.odpoved if hlasovani else Znalost.Odpoved.CIRCA | 			return hlasovani.odpoved if hlasovani else Znalost.Odpoved.CIRCA | ||||||
| 
 | 
 | ||||||
|  | @ -99,6 +110,7 @@ def newPrednaska(request): | ||||||
| 		], prefix=ZNALOSTI_PREFIX) | 		], prefix=ZNALOSTI_PREFIX) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 	# V případě nePOSTu nebo chyby při ukládání vracíme hlasování | ||||||
| 	return render( | 	return render( | ||||||
| 		request, | 		request, | ||||||
| 		'prednasky/base.html', | 		'prednasky/base.html', | ||||||
|  | @ -110,15 +122,21 @@ def newPrednaska(request): | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def Prednaska_hotovo(request): | def Prednaska_hotovo(request: HttpRequest) -> HttpResponse: | ||||||
|  | 	""" View po vyplnění :py:func:`hlasování <prednasky.views.newPrednaska>` """ | ||||||
| 	return formularOKView(request, "Děkujeme za vyplnění hlasování o přednáškách a těšíme se na soustředění.") | 	return formularOKView(request, "Děkujeme za vyplnění hlasování o přednáškách a těšíme se na soustředění.") | ||||||
| 
 | 
 | ||||||
| class MetaSeznamListView(generic.ListView): | class MetaSeznamListView(generic.ListView): | ||||||
|  | 	""" Seznam všech :py:class:`Seznamů <prednasky.models.Seznam>` s odkazy na exporty """ | ||||||
| 	model = Seznam | 	model = Seznam | ||||||
| 	template_name = 'prednasky/metaseznam_prednasek.html' | 	template_name = 'prednasky/metaseznam_prednasek.html' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class SeznamListView(generic.ListView): | class SeznamListView(generic.ListView): | ||||||
|  | 	""" | ||||||
|  | 		Náhled na to, kolik má která přednáška v :py:class:`Seznamu <prednasky.models.Seznam>` :py:class:`hlasů <prednasky.models.Hlasovani.Body>`. | ||||||
|  | 		(Je otázka, zda tento View vůbec chceme. Pokud ano, hodilo by se do něj přidat i znalosti.) | ||||||
|  | 	""" | ||||||
| 	template_name = 'prednasky/seznam_prednasek.html' | 	template_name = 'prednasky/seznam_prednasek.html' | ||||||
| 
 | 
 | ||||||
| 	def get_queryset(self): | 	def get_queryset(self): | ||||||
|  | @ -172,10 +190,19 @@ class SeznamListView(generic.ListView): | ||||||
| # 	) | # 	) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def PrednaskyExportView(request, seznam: int, **kwargs): | def PrednaskyExportView(request: HttpRequest, seznam: int, **kwargs) -> HttpResponse: | ||||||
|  | 	""" | ||||||
|  | 		Vrátí všechna :py:class:`Hlasování <prednasky.models.Hlasovani>` | ||||||
|  | 		i :py:class:`HlasováníOZnalostech <prednasky.models.HlasovaniOZnalostech>` | ||||||
|  | 		v daném :py:class:`Seznamu <prednasky.models.Seznam>` | ||||||
|  | 		jako csv soubor (řádky = účastníci, sloupce = přednášky&znalosti). | ||||||
|  | 
 | ||||||
|  | 		:param seznam: ID daného :py:class:`Seznamu <prednasky.models.Seznam>` | ||||||
|  | 	""" | ||||||
| 	hlasovani = Hlasovani.objects.filter(seznam=seznam).select_related("prednaska") | 	hlasovani = Hlasovani.objects.filter(seznam=seznam).select_related("prednaska") | ||||||
| 	hlasovani_o_znalostech = HlasovaniOZnalostech.objects.filter(seznam=seznam).select_related('ucastnik', 'znalost') | 	hlasovani_o_znalostech = HlasovaniOZnalostech.objects.filter(seznam=seznam).select_related('ucastnik', 'znalost') | ||||||
| 
 | 
 | ||||||
|  | 	# Inicializujeme sloupce | ||||||
| 	prednasky = list(Prednaska.objects.filter(seznamy=seznam)) | 	prednasky = list(Prednaska.objects.filter(seznamy=seznam)) | ||||||
| 	znalosti = list(Znalost.objects.filter(seznamy=seznam)) | 	znalosti = list(Znalost.objects.filter(seznamy=seznam)) | ||||||
| 
 | 
 | ||||||
|  | @ -184,26 +211,27 @@ def PrednaskyExportView(request, seznam: int, **kwargs): | ||||||
| 	znalosti_map: dict[int, int] = {z.id: i for i, z in enumerate(znalosti, offset + 1)} | 	znalosti_map: dict[int, int] = {z.id: i for i, z in enumerate(znalosti, offset + 1)} | ||||||
| 	width = offset + len(znalosti_map) | 	width = offset + len(znalosti_map) | ||||||
| 
 | 
 | ||||||
|  | 	# A po inicializaci sloupců vyplníme tabulku | ||||||
| 	table: [str, list[str|Prednaska|Znalost,]] = {} | 	table: [str, list[str|Prednaska|Znalost,]] = {} | ||||||
| 
 | 
 | ||||||
| 	for h in hlasovani: | 	for h in hlasovani: | ||||||
| 		if h.ucastnik not in table: | 		if h.ucastnik not in table: # Pokud jsme účastníka ještě neviděli, předgenerujeme si jeho řádek | ||||||
| 			table[h.ucastnik] = [h.ucastnik] + ([""] * width) | 			table[h.ucastnik] = [h.ucastnik] + ([""] * width) | ||||||
| 
 | 
 | ||||||
| 		if h.prednaska.id in prednasky_map: | 		if h.prednaska.id in prednasky_map: | ||||||
| 			table[h.ucastnik][prednasky_map[h.prednaska.id]] = h.body | 			table[h.ucastnik][prednasky_map[h.prednaska.id]] = h.body | ||||||
| 		else: | 		else: | ||||||
| 			pass # Padat hlasitě? | 			pass # TODO Padat hlasitě? | ||||||
| 
 | 
 | ||||||
| 	for h in hlasovani_o_znalostech: | 	for h in hlasovani_o_znalostech: | ||||||
| 		ucastnik = str(h.ucastnik) + ' ' + str(h.ucastnik.id) # id, kvůli kolizi jmen | 		ucastnik = str(h.ucastnik) + ' ' + str(h.ucastnik.id) # id, kvůli kolizi jmen | ||||||
| 		if ucastnik not in table: | 		if ucastnik not in table: # Pokud jsme účastníka ještě neviděli, předgenerujeme si jeho řádek | ||||||
| 			table[ucastnik] = [ucastnik] + ([""] * width) | 			table[ucastnik] = [ucastnik] + ([""] * width) | ||||||
| 
 | 
 | ||||||
| 		if h.znalost.id in znalosti_map: | 		if h.znalost.id in znalosti_map: | ||||||
| 			table[ucastnik][znalosti_map[h.znalost.id]] = h.odpoved | 			table[ucastnik][znalosti_map[h.znalost.id]] = h.odpoved | ||||||
| 		else: | 		else: | ||||||
| 			pass # Padat hlasitě? | 			pass # TODO Padat hlasitě? | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	response = HttpResponse(content_type="text/csv", charset="utf-8") | 	response = HttpResponse(content_type="text/csv", charset="utf-8") | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue