Přednášky #87
|  | @ -10,7 +10,7 @@ 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>` | 		:py:class:`Inline <django.contrib.admin.TabularInline>` pro :py:class:`prednasky.admin.SeznamAdmin` zobrazující :py:class:`Přednášky <prednasky.models.Prednaska>` | ||||||
| 		v adminu :py:class:`Seznamu <prednasky.models.Seznam>`. | 		v adminu :py:class:`Seznamu <prednasky.models.Seznam>`. | ||||||
| 	""" | 	""" | ||||||
| 
				
				zelvuska marked this conversation as resolved
				
			 | |||||||
| 	model = Prednaska.seznamy.through | 	model = Prednaska.seznamy.through | ||||||
|  | @ -60,7 +60,7 @@ class Seznam_PrednaskaInline(admin.TabularInline): | ||||||
| 
 | 
 | ||||||
| class Seznam_ZnalostInline(admin.TabularInline): | class Seznam_ZnalostInline(admin.TabularInline): | ||||||
| 	""" | 	""" | ||||||
| 		Pomůcka pro :py:class:`prednasky.admin.SeznamAdmin` zobrazující hezky :py:class:`Znalosti <prednasky.models.Znalost>` | 		:py:class:`Inline <django.contrib.admin.TabularInline>` pro :py:class:`prednasky.admin.SeznamAdmin` zobrazující :py:class:`Znalosti <prednasky.models.Znalost>` | ||||||
| 		v adminu :py:class:`Seznamu <prednasky.models.Seznam>`. | 		v adminu :py:class:`Seznamu <prednasky.models.Seznam>`. | ||||||
| 	""" | 	""" | ||||||
| 	model = Znalost.seznamy.through | 	model = Znalost.seznamy.through | ||||||
|  | @ -97,7 +97,7 @@ admin.site.register(Seznam, SeznamAdmin) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class PrednaskaAdmin(VersionAdmin): | class PrednaskaAdmin(VersionAdmin): | ||||||
| 	""" Admin pro :py:class:`Přednášku <prednasky.models.Prednaska> """ | 	""" 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'] | ||||||
|  | @ -138,7 +138,7 @@ 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> | 		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ášť | 		TODO předělat, aby nedědila z :py:class:`prednasky.admin.PrednaskaAdmin`, ale společné věci byly zvlášť | ||||||
| 	""" | 	""" | ||||||
| 
				
				zelvuska marked this conversation as resolved
				
			 
				
					
						ledoian
						commented  Za  Za ``Znalost>`` má být `` ` ``, před ``prednasky.admin.PrednaskaAdmin`` má taky být `` ` ``. 
				
					
						zelvuska
						commented  Před PrednskaAdmin je… Před PrednskaAdmin je… | |||||||
| 	list_display = ("__str__",) | 	list_display = ("__str__",) | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ 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>` | 	""" :py:class:`Formulář <django.forms.Form>` 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) | 	(neobsahuje téměř nic, většina se musí doplnit jiným způsobem) | ||||||
| 	""" | 	""" | ||||||
| 
 | 
 | ||||||
|  | @ -17,7 +17,7 @@ class HlasovaniPrednaskaForm(forms.Form): | ||||||
| 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>` | 	""" :py:class:`Formulář <django.forms.Form>` 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) | 	(neobsahuje téměř nic, většina se musí doplnit jiným způsobem) | ||||||
| 	""" | 	""" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								prednasky/migrations/0023_hlasovani_ucastnik_osoba.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,20 @@ | ||||||
|  | # Generated by Django 4.2.16 on 2025-02-19 17:31 | ||||||
|  | 
 | ||||||
|  | from django.db import migrations, models | ||||||
|  | import django.db.models.deletion | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |         ('personalni', '0019_rename_upozorneni_resitel_upozornovat_na_opravy_reseni'), | ||||||
|  |         ('prednasky', '0022_preklep_u_odpovedi_hlasovanioznalostech'), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AddField( | ||||||
|  |             model_name='hlasovani', | ||||||
|  |             name='ucastnik_osoba', | ||||||
|  |             field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='personalni.osoba'), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  | @ -6,7 +6,7 @@ from personalni.models import Organizator, Osoba | ||||||
| 
 | 
 | ||||||
| class Seznam(models.Model): | class Seznam(models.Model): | ||||||
| 	""" | 	""" | ||||||
| 		Spojuje :py:class:`Přednášky <prednasky.models.Prednaska>` | 		Spojuje :py:class:`Přednášky <prednasky.models.Prednaska>` a :py:class:`Znalosti <prednasky.models.Znalost> | ||||||
| 		se :py:class:`Soustředěními <soustredeni.models.Soustredeni>`, | 		se :py:class:`Soustředěními <soustredeni.models.Soustredeni>`, | ||||||
| 		kde by mohly zaznít, nebo zazní/zazněly. | 		kde by mohly zaznít, nebo zazní/zazněly. | ||||||
| 	""" | 	""" | ||||||
|  | @ -19,8 +19,8 @@ class Seznam(models.Model): | ||||||
| 
 | 
 | ||||||
| 	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>`). """ | 		""" 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" #: odpovídá před-soustřeďkové představě o tom, jaké přednášky dělat (dá se o nich třeba hlasovat ap.) | ||||||
| 		BUDE = 2, "Bude" | 		BUDE = 2, "Bude" #: odpovídá definitivní představě o tom, co bude/bylo a dá se porovnávat s novými návrhy | ||||||
| 
 | 
 | ||||||
| 	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) | ||||||
|  | @ -88,6 +88,7 @@ class Hlasovani(models.Model): | ||||||
| 	#: že všechna předchozí hlasování zde mají náhodný string…) | 	#: že všechna předchozí hlasování zde mají náhodný string…) | ||||||
| 	#: TODO Změnit to na Osobu* | 	#: TODO Změnit to na Osobu* | ||||||
| 	ucastnik = models.CharField("Účastník", max_length=100) | 	ucastnik = models.CharField("Účastník", max_length=100) | ||||||
| 
				
				zelvuska marked this conversation as resolved
				
			 
				
					
						ledoian
						commented  Hmm, existuje čisté a praktické řešení. To čisté a datazachovávající je mít pro osobu nový FK (s  Praktické řešení je se na původní hlasy vykašlat, buď je dropnout úplně, nebo jim nastavit Osobu na NULL a pak sice nepůjde dohledat, kdo hlasoval k čemu, ale aspoň informace o zájmu v každém seznamu přežije. (Myslím, že ta druhá varianta vyžaduje zbytečně moc hackování třeba exportů, takže za to nestojí…) Hmm, existuje čisté a praktické řešení. To čisté a datazachovávající je mít pro osobu nový FK (s `null=True, blank=False`) a mít stará řešení se string-účastníkem a nová s Osobou.
Praktické řešení je se na původní hlasy vykašlat, buď je dropnout úplně, nebo jim nastavit Osobu na NULL a pak sice nepůjde dohledat, kdo hlasoval k čemu, ale aspoň informace o zájmu v každém seznamu přežije. (Myslím, že ta druhá varianta vyžaduje zbytečně moc hackování třeba exportů, takže za to nestojí…) 
				
					
						ledoian
						commented  Also: tu Osobu (s null=True) si IMHO chceme ukládat už teď, ať pak můžeme zmigrovat a nechybí nám data… (původní hlasovátko ještě nevědělo nic o účastnických uživatelích/osobách…) Also: tu Osobu (s null=True) si IMHO chceme ukládat už teď, ať pak můžeme zmigrovat a nechybí nám data… (původní hlasovátko ještě nevědělo nic o účastnických uživatelích/osobách…) | |||||||
|  | 	ucastnik_osoba = models.ForeignKey(Osoba, on_delete=models.CASCADE, blank=False, null=True) | ||||||
| 	seznam = models.ForeignKey(Seznam, null=True, on_delete=models.SET_NULL) | 	seznam = models.ForeignKey(Seznam, null=True, on_delete=models.SET_NULL) | ||||||
| 
 | 
 | ||||||
| 	def __str__(self): | 	def __str__(self): | ||||||
|  | @ -98,6 +99,9 @@ class Znalost(models.Model): | ||||||
| 	""" | 	""" | ||||||
| 		Reprezentuje znalost, na kterou se můžeme účastníka ptát (nechat je hlasovat). | 		Reprezentuje znalost, na kterou se můžeme účastníka ptát (nechat je hlasovat). | ||||||
| 		(Viz :py:class:`HlasováníOZnalostech <prednasky.models.HlasovaniOZnalostech>`.) | 		(Viz :py:class:`HlasováníOZnalostech <prednasky.models.HlasovaniOZnalostech>`.) | ||||||
|  | 
 | ||||||
|  | 		(V podstatě :py:class:`Přednáška <prednasky.models.Prednaska>, jen neobsahuje | ||||||
|  | 		tolik detailů a v hlasování má jiné odpovědi.) | ||||||
| 	""" | 	""" | ||||||
| 	class Meta: | 	class Meta: | ||||||
| 		db_table = "prednasky_znalost" | 		db_table = "prednasky_znalost" | ||||||
|  | @ -117,6 +121,9 @@ class HlasovaniOZnalostech(models.Model): | ||||||
| 		Reprezentuje hlasování jednoho účastníka | 		Reprezentuje hlasování jednoho účastníka | ||||||
| 		o jedné :py:class:`Znalosti <prednasky.models.Znalost>` | 		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) | 		v jednom :py:class:`Seznamu <prednasky.models.Seznam>` (účastníkův pohled se totiž mezi sousy změnit) | ||||||
|  | 
 | ||||||
|  | 		(V podstatě totéž, co :py:class:`Hlasování <prednasky.models.Hlasovani>`, jen má jiné komentáře | ||||||
|  | 		u odpovědí a místo přednášky odkazuje na znalost.) | ||||||
| 	""" | 	""" | ||||||
| 	class Odpoved(models.IntegerChoices): | 	class Odpoved(models.IntegerChoices): | ||||||
| 		""" Na kolik danou znalost účastník ovládá v daném Hlasování (větší číslo = víc zná) """ | 		""" Na kolik danou znalost účastník ovládá v daném Hlasování (větší číslo = víc zná) """ | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
| <p>Obtížnost 1 je nejlehčí, 3 nejtěžší.</p> | <p>Obtížnost 1 je nejlehčí, 3 nejtěžší.</p> | ||||||
|   {{ form_set_prednasky.management_form }} |   {{ form_set_prednasky.management_form }} | ||||||
|   {% for f, p in formy_a_prednasky %} |   {% for f, p in formy_a_prednasky %} | ||||||
|  |     <div class="hlasovani-prednaska"> | ||||||
|     <h4>{{p.nazev}} ({{p.org}})</h4> |     <h4>{{p.nazev}} ({{p.org}})</h4> | ||||||
|     <p class="textprednasky">{{p.anotace | linebreaksbr}}</p> |     <p class="textprednasky">{{p.anotace | linebreaksbr}}</p> | ||||||
|     <label>Obor: </label> {{p.obor}}<br> |     <label>Obor: </label> {{p.obor}}<br> | ||||||
|  | @ -22,17 +23,20 @@ | ||||||
|     <br> |     <br> | ||||||
|     {{ f }} |     {{ f }} | ||||||
|     <br> |     <br> | ||||||
|  |     </div> | ||||||
|   {% empty %} |   {% empty %} | ||||||
|     Nejsou žádné přednášky o kterých by šlo hlasovat. |     Nejsou žádné přednášky o kterých by šlo hlasovat. | ||||||
|   {% endfor %} |   {% endfor %} | ||||||
| 
 | 
 | ||||||
|   {{ form_set_znalosti.management_form }} |   {{ form_set_znalosti.management_form }} | ||||||
|   {% for f, z in formy_a_znalosti %} |   {% for f, z in formy_a_znalosti %} | ||||||
|  |     <div class="hlasovani-znalost"> | ||||||
|     {% if forloop.first %}<hr/><h3>Jak moc znáš následující?</h3>{% endif %} |     {% if forloop.first %}<hr/><h3>Jak moc znáš následující?</h3>{% endif %} | ||||||
|     <h4>{{z.nazev}}</h4> |     <h4>{{z.nazev}}</h4> | ||||||
|     <p class="textznalosti">{{z.text | linebreaksbr}}</p> |     <p class="textznalosti">{{z.text | linebreaksbr}}</p> | ||||||
|     {{ f }} |     {{ f }} | ||||||
|     <br> |     <br> | ||||||
|  |     </div> | ||||||
|   {% endfor %} |   {% endfor %} | ||||||
|   <input type="submit" value="Odeslat"/> |   <input type="submit" value="Odeslat"/> | ||||||
| </form> | </form> | ||||||
|  |  | ||||||
|  | @ -2,19 +2,19 @@ | ||||||
| 
 | 
 | ||||||
| {% block content %} | {% block content %} | ||||||
|   <h1>{% block nadpis1a %} |   <h1>{% block nadpis1a %} | ||||||
| 	  Hlasování o přednáškách | 	  Výsledky hlasování o přednáškách | ||||||
| 	  {% endblock %}</h1> | 	  {% endblock %}</h1> | ||||||
|   {# Projdi vsechny seznamy #} |   {# Projdi vsechny seznamy #} | ||||||
|   <div class="mam-org-only"> |   <div class="mam-org-only"> | ||||||
|   <ul> |   <ul> | ||||||
|   {% for seznam in object_list %} |   {% for seznam in object_list %} | ||||||
|     <li> |     <li> | ||||||
|     {% if seznam.stav == 1 %} {# STAV_NAHRH = 1 #}  |     {% if seznam.stav == seznam.Stav.NAVRH %} | ||||||
|         <a href="/prednasky/seznam_prednasek/{{seznam.id}}">Návrh přednášek na soustředění {{seznam.soustredeni.misto}} </a> |       Návrh přednášek na soustředění {{seznam.soustredeni.misto}} | ||||||
|     {% else %} |     {% else %} | ||||||
|         <a href="/prednasky/seznam_prednasek/{{seznam.id}}">Seznam přednášek na soustředění {{seznam.soustredeni.misto}} </a> |       Seznam přednášek na soustředění {{seznam.soustredeni.misto}} | ||||||
|     {% endif %} |     {% endif %} | ||||||
|     <a href="/prednasky/seznam_prednasek/{{seznam.id}}/hlasovani.csv">Export</a> |       (<a href='{% url "seznam-export-csv" seznam=seznam.id %}'>CSV</a>) | ||||||
|     </li> |     </li> | ||||||
|   {% endfor %} |   {% endfor %} | ||||||
|   </ul> |   </ul> | ||||||
|  |  | ||||||
|  | @ -12,19 +12,9 @@ urlpatterns = [ | ||||||
| 		'prednasky/metaseznam_prednasek', | 		'prednasky/metaseznam_prednasek', | ||||||
| 		org_required(views.MetaSeznamListView.as_view()), | 		org_required(views.MetaSeznamListView.as_view()), | ||||||
| 		name='metaseznam-list'), | 		name='metaseznam-list'), | ||||||
| 	# path( |  | ||||||
| 	# 	'prednasky/seznam_prednasek/<int:seznam>/export', |  | ||||||
| 	# 	org_required(views.SeznamExportView), |  | ||||||
| 	# 	name='seznam-export' |  | ||||||
| 	# ), |  | ||||||
| 	path( | 	path( | ||||||
| 		'prednasky/seznam_prednasek/<int:seznam>/hlasovani.csv', | 		'prednasky/seznam_prednasek/<int:seznam>/hlasovani.csv', | ||||||
| 		org_required(views.PrednaskyExportView), | 		org_required(views.PrednaskyExportView), | ||||||
| 		name='seznam-export-csv' | 		name='seznam-export-csv' | ||||||
| 	), | 	), | ||||||
| 	path( |  | ||||||
| 		'prednasky/seznam_prednasek/<int:seznam>/', |  | ||||||
| 		org_required(views.SeznamListView.as_view()), |  | ||||||
| 		name='seznam-list' |  | ||||||
| 	), |  | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | @ -64,6 +64,7 @@ def newPrednaska(request: HttpRequest) -> HttpResponse: | ||||||
| 						prednaska=prednaska, | 						prednaska=prednaska, | ||||||
| 						body=form.cleaned_data['body'], | 						body=form.cleaned_data['body'], | ||||||
| 						ucastnik=ucastnik, | 						ucastnik=ucastnik, | ||||||
|  | 						ucastnik_osoba=osoba, | ||||||
| 						seznam=seznam, | 						seznam=seznam, | ||||||
| 					) | 					) | ||||||
| 
 | 
 | ||||||
|  | @ -116,8 +117,8 @@ def newPrednaska(request: HttpRequest) -> HttpResponse: | ||||||
| 		'prednasky/base.html', | 		'prednasky/base.html', | ||||||
| 		{ | 		{ | ||||||
| 			'form_set_prednasky': form_set_prednasky, 'form_set_znalosti': form_set_znalosti, | 			'form_set_prednasky': form_set_prednasky, 'form_set_znalosti': form_set_znalosti, | ||||||
| 			'formy_a_prednasky': zip(form_set_prednasky, prednasky), | 			'formy_a_prednasky': list(zip(form_set_prednasky, prednasky)), | ||||||
| 			'formy_a_znalosti': zip(form_set_znalosti, znalosti), | 			'formy_a_znalosti': list(zip(form_set_znalosti, znalosti)), | ||||||
| 		} | 		} | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
|  | @ -132,64 +133,6 @@ class MetaSeznamListView(generic.ListView): | ||||||
| 	template_name = 'prednasky/metaseznam_prednasek.html' | 	template_name = 'prednasky/metaseznam_prednasek.html' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 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' |  | ||||||
| 
 |  | ||||||
| 	def get_queryset(self): |  | ||||||
| 		self.seznam = get_object_or_404(Seznam, id=self.kwargs["seznam"]) |  | ||||||
| 		prednasky = Prednaska.objects.filter(seznamy=self.seznam).order_by( |  | ||||||
| 			'org__osoba__user__first_name', 'org__osoba__user__last_name' |  | ||||||
| 		) |  | ||||||
| 		return prednasky |  | ||||||
| 
 |  | ||||||
| 	# FIXME nahradit anotaci s filtrem po prechodu na Django 2.2 |  | ||||||
| 	def get_context_data(self,**kwargs): |  | ||||||
| 		context = super(SeznamListView, self).get_context_data(**kwargs) |  | ||||||
| 
 |  | ||||||
| 		# hlasovani se vztahuje k nejnovejsimu soustredeni |  | ||||||
| 		sous = Soustredeni.objects.first() |  | ||||||
| 		seznam = Seznam.objects.filter(soustredeni = sous, stav=Seznam.Stav.NAVRH).first() |  | ||||||
| 	 |  | ||||||
| 		for obj in self.object_list: |  | ||||||
| 			hlasovani_set = obj.hlasovani_set.filter(seznam=seznam).only('body') |  | ||||||
| 			obj.body = sum(map(lambda x: x.body,hlasovani_set)) |  | ||||||
| 
 |  | ||||||
| 		return context |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| # def SeznamExportView(request, seznam): |  | ||||||
| # 	"""Vypíše výsledky hlasování ve formátu pro prologovský optimalizátor""" |  | ||||||
| # 	# TODO zřejmě se nepoužívá, časem vyřadit? nahradit tabulkou vhodnější pro |  | ||||||
| # 	# lidi? |  | ||||||
| # 	hlasovani = Hlasovani.objects.filter(seznam=seznam) |  | ||||||
| # 	prednasky = Prednaska.objects.filter(seznamy=seznam) |  | ||||||
| # 	orgove = set(p.org for p in prednasky) |  | ||||||
| # 	ucastnici = set(h.ucastnik for h in hlasovani) |  | ||||||
| # |  | ||||||
| # 	for p in prednasky: |  | ||||||
| # 		p.body = [] |  | ||||||
| # 		for u in ucastnici: |  | ||||||
| # 			try: |  | ||||||
| # 				p.body.append(hlasovani.get(ucastnik=u, prednaska=p).body) |  | ||||||
| # 			except ObjectDoesNotExist: |  | ||||||
| # 				# účastník nehlasoval |  | ||||||
| # 				p.body.append("?") |  | ||||||
| # |  | ||||||
| # 	for h in hlasovani: |  | ||||||
| # 		h.ucastnik = hash(h.ucastnik) |  | ||||||
| # |  | ||||||
| # 	return render( |  | ||||||
| # 		request, |  | ||||||
| # 		'prednasky/seznam_prednasek_export.txt', |  | ||||||
| # 		{"hlasovani": hlasovani, "prednasky": prednasky, "orgove": orgove}, |  | ||||||
| # 		content_type="text/plain" |  | ||||||
| # 	) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def PrednaskyExportView(request: HttpRequest, seznam: int, **kwargs) -> HttpResponse: | def PrednaskyExportView(request: HttpRequest, seznam: int, **kwargs) -> HttpResponse: | ||||||
| 	""" | 	""" | ||||||
| 		Vrátí všechna :py:class:`Hlasování <prednasky.models.Hlasovani>` | 		Vrátí všechna :py:class:`Hlasování <prednasky.models.Hlasovani>` | ||||||
|  | @ -214,6 +157,8 @@ def PrednaskyExportView(request: HttpRequest, seznam: int, **kwargs) -> HttpResp | ||||||
| 	# A po inicializaci sloupců vyplníme tabulku | 	# A po inicializaci sloupců vyplníme tabulku | ||||||
| 	table: [str, list[str|Prednaska|Znalost,]] = {} | 	table: [str, list[str|Prednaska|Znalost,]] = {} | ||||||
| 
 | 
 | ||||||
|  | 	errors = [] | ||||||
|  | 
 | ||||||
| 	for h in hlasovani: | 	for h in hlasovani: | ||||||
| 		if h.ucastnik not in table: # Pokud jsme účastníka ještě neviděli, předgenerujeme si jeho řádek | 		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) | ||||||
|  | @ -221,7 +166,7 @@ def PrednaskyExportView(request: HttpRequest, seznam: int, **kwargs) -> HttpResp | ||||||
| 		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 # TODO Padat hlasitě? | 			errors.append(f"Přednáška {h.prednaska.id} ({h.prednaska}) dostala od Účastníka {h.ucastnik} následující hodnocení: {h.body}") | ||||||
| 
 | 
 | ||||||
| 	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 | ||||||
|  | @ -231,8 +176,10 @@ def PrednaskyExportView(request: HttpRequest, seznam: int, **kwargs) -> HttpResp | ||||||
| 		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 # TODO Padat hlasitě? | 			errors.append(f"Znalost {h.znalost.id} ({h.znalost}) dostala od Účastníka {h.ucastnik.id} následující odpověď: {h.odpoved}") | ||||||
| 
 | 
 | ||||||
|  | 	if len(errors) > 0: | ||||||
|  | 		logger.error("Při exportování hlasování o přednáškách a znalostech se neexportovali hodnocení a přednášky (pravděpodobně se od hlasování vyškrtla nějaká znalost/přednáška ze seznamu):\n" + "\n".join(errors)) | ||||||
| 
 | 
 | ||||||
| 	response = HttpResponse(content_type="text/csv", charset="utf-8") | 	response = HttpResponse(content_type="text/csv", charset="utf-8") | ||||||
| 	response["Content-Disposition"] = 'attachment; filename="hlasovani.csv"' | 	response["Content-Disposition"] = 'attachment; filename="hlasovani.csv"' | ||||||
|  |  | ||||||
Nechceš tomu prostě říkat Inline a odkázat dokumentaci Djanga rovnou? Přijde mi, že znalý stejně vidí, že to je Inline a neznalému „Pomůcka zobrazující hezky“ dá zbytečně málo informace.
Navrhuji „Inline pro … zobrazující …“
(i dál)