Hlasování o přednáškách pomocí formsetů…
This commit is contained in:
		
							parent
							
								
									e12b614e1c
								
							
						
					
					
						commit
						fbd75d2f72
					
				
					 6 changed files with 122 additions and 58 deletions
				
			
		|  | @ -57,6 +57,7 @@ DOBA_ODHLASENI_PRI_ZASKRTNUTI_NEODHLASOVAT = 365 * 24 * 3600  # rok | |||
| CSRF_FAILURE_VIEW = 'various.views.csrf.csrf_error' | ||||
| 
 | ||||
| # Modules configuration | ||||
| FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer" | ||||
| 
 | ||||
| AUTHENTICATION_BACKENDS = ( | ||||
| 	'django.contrib.auth.backends.ModelBackend', | ||||
|  |  | |||
|  | @ -100,7 +100,7 @@ admin.site.register(Prednaska, PrednaskaAdmin) | |||
| 
 | ||||
| 
 | ||||
| class ZnalostAdmin(PrednaskaAdmin): # Trochu hack, ať nemusím vypisovat všechno znovu | ||||
| 	list_display = [] | ||||
| 	list_filter = [] | ||||
| 	list_display = ("__str__",) | ||||
| 	list_filter = () | ||||
| 
 | ||||
| admin.site.register(Znalost, ZnalostAdmin) | ||||
|  |  | |||
|  | @ -1 +1,15 @@ | |||
| from django import forms | ||||
| 
 | ||||
| from .models import Hlasovani, HlasovaniOZnalostech | ||||
| 
 | ||||
| class HlasovaniPrednaskaForm(forms.Form): | ||||
| 	prednaska_id = forms.IntegerField(widget=forms.HiddenInput) | ||||
| 	body = forms.ChoiceField(label=False, widget=forms.RadioSelect, choices=Hlasovani.Body.choices, initial=Hlasovani.Body.JEDNO) | ||||
| 
 | ||||
| HlasovaniPrednaskaFormSet = forms.formset_factory(HlasovaniPrednaskaForm, extra=0) | ||||
| 
 | ||||
| class HlasovaniZnalostiForm(forms.Form): | ||||
| 	znalost_id = forms.IntegerField(widget=forms.HiddenInput) | ||||
| 	odpoved = forms.ChoiceField(label=False, widget=forms.RadioSelect, choices=HlasovaniOZnalostech.Odpoved.choices) | ||||
| 
 | ||||
| HlasovaniZnalostiFormSet = forms.formset_factory(HlasovaniZnalostiForm, extra=0) | ||||
|  |  | |||
|  | @ -64,6 +64,10 @@ class Hlasovani(models.Model): | |||
| 	id = models.AutoField(primary_key=True) | ||||
| 	prednaska = models.ForeignKey(Prednaska, on_delete=models.CASCADE) | ||||
| 	body = models.IntegerField("Body", default=Body.JEDNO, choices=Body.choices) | ||||
| 
 | ||||
| 	# (přechod z jména na objekt Osoby nějak kape na tom, | ||||
| 	# ž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) | ||||
| 	seznam = models.ForeignKey(Seznam, null=True, on_delete=models.SET_NULL) | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,36 +5,36 @@ | |||
| 
 | ||||
| 
 | ||||
| {% block content %} | ||||
| <h1> | ||||
| {% block nadpis1a %}Hlasování o přednáškách{% endblock %} | ||||
| </h1> | ||||
| 
 | ||||
| <p> | ||||
| Jak moc by ses chtěl(a) zúčastnit následujících přednášek? | ||||
| <br> | ||||
| <span style="font-size: 75%">Obtížnost 1 je nejlehčí, 3 nejtěžší.</span> | ||||
| </p> | ||||
| <h1>{% block nadpis1a %}Hlasování o přednáškách{% endblock %}</h1> | ||||
| 
 | ||||
| <form enctype="multipart/form-data" action="." method="post"> | ||||
|   {% csrf_token %} | ||||
|   <table> | ||||
|     {% for p, h in prednasky %} | ||||
|     <tr><td><label>{{p.org}}: <span style="font-size: 175%">{{p.nazev}}</span></label></td></tr> | ||||
|     <tr><td><p><i>{{p.anotace}}</i></p></td></tr> | ||||
|     <tr><td><label>Obor: </label> {{p.obor}}</td></tr> | ||||
|     <tr><td><label>Obtížnost: </label> {{p.obtiznost}}</td>   </tr> | ||||
|     {% if p.klicova %}<tr><td><label>Klíčová slova: </label> {{p.klicova}}</td></tr>{% endif%} | ||||
|     <tr><td>Hodnocení: | ||||
|         <INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="-1" {% if h == -1 %} CHECKED="checked" {% endif %} > rozhodně nechci | ||||
|         <INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="0" {% if h == 0 %} CHECKED="checked" {% endif %}> je mi to jedno | ||||
|         <INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="1" {% if h == 1 %} CHECKED="checked" {% endif %}> rozhodně chci | ||||
|     </td></tr> | ||||
|     <tr><td> </td></tr> | ||||
|     {% empty %} | ||||
|       Nejsou žádné přednášky o kterých by šlo hlasovat. | ||||
|     {% endfor %} | ||||
|     <tr><td><input name="odeslat" type="submit" value="Odeslat"></td><tr> | ||||
|   </table> | ||||
| 
 | ||||
| <h3>Jak moc by ses chtěl(a) zúčastnit následujících přednášek?</h3> | ||||
| <p>Obtížnost 1 je nejlehčí, 3 nejtěžší.</p> | ||||
|   {{ form_set_prednasky.management_form }} | ||||
|   {% for f, p in formy_a_prednasky %} | ||||
|     <h4>{{p.nazev}} ({{p.org}})</h4> | ||||
|     <p class="textprednasky">{{p.anotace}}</p> | ||||
|     <label>Obor: </label> {{p.obor}}<br> | ||||
|     <label>Obtížnost: </label> {{p.obtiznost}}<br> | ||||
|     {% if p.klicova %}<label>Klíčová slova: </label> {{p.klicova}}<br>{% endif%} | ||||
|     <br> | ||||
|     {{ f }} | ||||
|     <br> | ||||
|   {% empty %} | ||||
|     Nejsou žádné přednášky o kterých by šlo hlasovat. | ||||
|   {% endfor %} | ||||
| 
 | ||||
|   {{ form_set_znalosti.management_form }} | ||||
|   {% for f, z in formy_a_znalosti %} | ||||
|     {% if forloop.first %}<hr/><h3>Jak moc znáš následující?</h3>{% endif %} | ||||
|     <h4>{{z.nazev}}</h4> | ||||
|     <p class="textznalosti">{{z.text}}</p> | ||||
|     {{ f }} | ||||
|     <br> | ||||
|   {% endfor %} | ||||
|   <input type="submit" value="Odeslat"/> | ||||
| </form> | ||||
|     | ||||
| {% endblock %} | ||||
|  |  | |||
|  | @ -1,19 +1,25 @@ | |||
| import http | ||||
| import logging | ||||
| 
 | ||||
| from django.shortcuts import render, get_object_or_404 | ||||
| from django.views import generic | ||||
| from django.shortcuts import HttpResponseRedirect | ||||
| from django.core.exceptions import ObjectDoesNotExist | ||||
| from django.db.models import Sum | ||||
| from django.forms import Form | ||||
| from django.db import transaction | ||||
| 
 | ||||
| from various.views.pomocne import formularOKView | ||||
| from .forms import HlasovaniPrednaskaFormSet, HlasovaniZnalostiFormSet | ||||
| 
 | ||||
| from various.models import Nastaveni | ||||
| from prednasky.models import Prednaska, Hlasovani, Seznam | ||||
| from prednasky.models import Prednaska, Hlasovani, Znalost, HlasovaniOZnalostech, Seznam | ||||
| from soustredeni.models import Soustredeni | ||||
| from personalni.models import Osoba | ||||
| 
 | ||||
| PREDNASKY_PREFIX = "prednasky" | ||||
| ZNALOSTI_PREFIX = "znalosti" | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
| def newPrednaska(request): | ||||
| 	# hlasovani se vztahuje k nejnovejsimu soustredeni | ||||
| 	sous = Nastaveni.get_solo().aktualni_sous | ||||
|  | @ -23,43 +29,82 @@ def newPrednaska(request): | |||
| 			'title': "Nelze hlasovat", | ||||
| 			'text': "Není žádný seznam přednášek, o kterém by se dalo hlasovat.", | ||||
| 		}, status=http.HTTPStatus.NOT_FOUND) | ||||
| 
 | ||||
| 	osoba = Osoba.objects.filter(user=request.user).first() | ||||
| 	ucastnik = osoba.plne_jmeno() + ' ' + str(osoba.id) | ||||
| 	# obsluha formulare | ||||
| 
 | ||||
| 	if request.method == 'POST': | ||||
| 		form = Form(request.POST, request.FILES) | ||||
| 		if form.is_valid(): | ||||
| 			# id z důvodu duplicitních jmen (přechod z jména na objekt Osoby nějak kape na tom, | ||||
| 			# že všechna předchozí hlasování zde mají náhodný string…) | ||||
| 			# TODO Změnit to na Osobu | ||||
| 		form_set_prednasky = HlasovaniPrednaskaFormSet(request.POST, prefix=PREDNASKY_PREFIX) | ||||
| 		form_set_znalosti = HlasovaniZnalostiFormSet(request.POST, prefix=ZNALOSTI_PREFIX) | ||||
| 
 | ||||
| 			# TODO v následujících řádcích je zbytečně mnoho dotazů na QuerySet (pokud účastník hlasoval, hlasoval u všech) | ||||
| 			for i in request.POST: | ||||
| 				if i[0] == 'q': | ||||
| 					prednaska = Prednaska.objects.filter(pk=int(i[1:]))[0] | ||||
| 					hlasovani = Hlasovani.objects.filter(ucastnik=ucastnik, prednaska=prednaska).first() | ||||
| 					if not hlasovani: | ||||
| 						hlasovani = Hlasovani() | ||||
| 						hlasovani.prednaska = prednaska | ||||
| 						hlasovani.ucastnik = ucastnik | ||||
| 						hlasovani.seznam = seznam | ||||
| 					hlasovani.body = int(request.POST[i]) | ||||
| 					hlasovani.save() | ||||
| 		if form_set_prednasky.is_valid() and form_set_znalosti.is_valid(): | ||||
| 			with transaction.atomic(): | ||||
| 				seznam.hlasovani_set.filter(ucastnik=ucastnik).delete() | ||||
| 				seznam.hlasovanioznalostech_set.filter(ucastnik=osoba).delete() | ||||
| 
 | ||||
| 				for form in form_set_prednasky: | ||||
| 					prednaska_id = form.cleaned_data['prednaska_id'] | ||||
| 					prednaska = Prednaska.objects.filter(id=prednaska_id).first() | ||||
| 					if prednaska is None: | ||||
| 						logger.error(f"Účastník {ucastnik} hodnotil neexistující přednášku {prednaska_id} číslem {form.cleaned_data['body']}") | ||||
| 						continue | ||||
| 
 | ||||
| 					Hlasovani.objects.create( | ||||
| 						prednaska=prednaska, | ||||
| 						body=form.cleaned_data['body'], | ||||
| 						ucastnik=ucastnik, | ||||
| 						seznam=seznam, | ||||
| 					) | ||||
| 
 | ||||
| 				for form in form_set_znalosti: | ||||
| 					znalost_id = form.cleaned_data['znalost_id'] | ||||
| 					znalost = Znalost.objects.filter(id=znalost_id).first() | ||||
| 					if znalost is None: | ||||
| 						logger.error(f"Účastník {ucastnik} hodnotil neexistující znalost {znalost_id} číslem {form.cleaned_data['odpoved']}") | ||||
| 						continue | ||||
| 
 | ||||
| 					HlasovaniOZnalostech.objects.create( | ||||
| 						odpoved=form.cleaned_data['odpoved'], | ||||
| 						znalost=znalost, | ||||
| 						ucastnik=osoba, | ||||
| 						seznam=seznam, | ||||
| 					) | ||||
| 
 | ||||
| 			# presmerovani na prave vzniklou galerii | ||||
| 			return HttpResponseRedirect('./hotovo') | ||||
| 
 | ||||
| 	def prednaska_hodnoceni(prednaska): | ||||
| 		h = Hlasovani.objects.filter(ucastnik=ucastnik, prednaska=prednaska).first() | ||||
| 		if h: | ||||
| 			return prednaska, h.body | ||||
| 		else: | ||||
| 			return prednaska, 0 | ||||
| 			prednasky = seznam.prednaska_set.all() | ||||
| 			znalosti = seznam.znalost_set.all() | ||||
| 			# Spadnout, pokud nesedí přednáška/znalost s formulářem. (Nějak se mi to nepovedlo.) | ||||
| 
 | ||||
| 	else: | ||||
| 		def odpoved_prednasky(p): | ||||
| 			hlasovani = p.hlasovani_set.filter(ucastnik=ucastnik).first() | ||||
| 			return hlasovani.body if hlasovani else Hlasovani.Body.JEDNO | ||||
| 
 | ||||
| 		def odpoved_znalosti(z): | ||||
| 			hlasovani = z.hlasovanioznalostech_set.filter(ucastnik=osoba).first() | ||||
| 			return hlasovani.odpoved if hlasovani else Hlasovani.Body.JEDNO | ||||
| 
 | ||||
| 		prednasky = seznam.prednaska_set.all() | ||||
| 		znalosti = seznam.znalost_set.all() | ||||
| 
 | ||||
| 		form_set_prednasky = HlasovaniPrednaskaFormSet(initial=[ | ||||
| 			{"prednaska_id": p.id, "body": odpoved_prednasky(p)} for p in prednasky | ||||
| 		], prefix=PREDNASKY_PREFIX) | ||||
| 
 | ||||
| 		form_set_znalosti = HlasovaniZnalostiFormSet(initial=[ | ||||
| 			{"znalost_id": z.id, "odpoved": odpoved_znalosti(z)} for z in znalosti | ||||
| 		], prefix=ZNALOSTI_PREFIX) | ||||
| 
 | ||||
| 
 | ||||
| 	return render( | ||||
| 		request, | ||||
| 		'prednasky/base.html', | ||||
| 		{'prednasky': map(prednaska_hodnoceni, seznam.prednaska_set.all())} | ||||
| 		{ | ||||
| 			'form_set_prednasky': form_set_prednasky, 'form_set_znalosti': form_set_znalosti, | ||||
| 			'formy_a_prednasky': zip(form_set_prednasky, prednasky), | ||||
| 			'formy_a_znalosti': zip(form_set_znalosti, znalosti), | ||||
| 		} | ||||
| 	) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue