Compare commits

..

No commits in common. "90e7b97b85402910c51bc1de99509b99b17e1257" and "174087edc7101059a18e63b38b2376dc711a1a14" have entirely different histories.

10 changed files with 211 additions and 396 deletions

View file

@ -14,12 +14,12 @@
"flatpage" "flatpage"
], ],
[ [
"change_flatpage", "delete_flatpage",
"flatpages", "flatpages",
"flatpage" "flatpage"
], ],
[ [
"delete_flatpage", "change_flatpage",
"flatpages", "flatpages",
"flatpage" "flatpage"
], ],
@ -34,12 +34,12 @@
"galerie" "galerie"
], ],
[ [
"change_galerie", "delete_galerie",
"galerie", "galerie",
"galerie" "galerie"
], ],
[ [
"delete_galerie", "change_galerie",
"galerie", "galerie",
"galerie" "galerie"
], ],
@ -54,12 +54,12 @@
"obrazek" "obrazek"
], ],
[ [
"change_obrazek", "delete_obrazek",
"galerie", "galerie",
"obrazek" "obrazek"
], ],
[ [
"delete_obrazek", "change_obrazek",
"galerie", "galerie",
"obrazek" "obrazek"
], ],
@ -104,12 +104,12 @@
"komentar" "komentar"
], ],
[ [
"change_komentar", "delete_komentar",
"korektury", "korektury",
"komentar" "komentar"
], ],
[ [
"delete_komentar", "change_komentar",
"korektury", "korektury",
"komentar" "komentar"
], ],
@ -124,12 +124,12 @@
"korekturovanepdf" "korekturovanepdf"
], ],
[ [
"change_korekturovanepdf", "delete_korekturovanepdf",
"korektury", "korektury",
"korekturovanepdf" "korekturovanepdf"
], ],
[ [
"delete_korekturovanepdf", "change_korekturovanepdf",
"korektury", "korektury",
"korekturovanepdf" "korekturovanepdf"
], ],
@ -144,12 +144,12 @@
"oprava" "oprava"
], ],
[ [
"change_oprava", "delete_oprava",
"korektury", "korektury",
"oprava" "oprava"
], ],
[ [
"delete_oprava", "change_oprava",
"korektury", "korektury",
"oprava" "oprava"
], ],
@ -164,12 +164,12 @@
"novinky" "novinky"
], ],
[ [
"change_novinky", "delete_novinky",
"novinky", "novinky",
"novinky" "novinky"
], ],
[ [
"delete_novinky", "change_novinky",
"novinky", "novinky",
"novinky" "novinky"
], ],
@ -204,12 +204,12 @@
"prijemce" "prijemce"
], ],
[ [
"change_prijemce", "delete_prijemce",
"personalni", "personalni",
"prijemce" "prijemce"
], ],
[ [
"delete_prijemce", "change_prijemce",
"personalni", "personalni",
"prijemce" "prijemce"
], ],
@ -234,12 +234,12 @@
"skola" "skola"
], ],
[ [
"change_skola", "delete_skola",
"personalni", "personalni",
"skola" "skola"
], ],
[ [
"delete_skola", "change_skola",
"personalni", "personalni",
"skola" "skola"
], ],
@ -249,14 +249,24 @@
"skola" "skola"
], ],
[ [
"view_hlasovani", "add_hlasovani",
"prednasky", "prednasky",
"hlasovani" "hlasovani"
], ],
[ [
"view_hlasovanioznalostech", "delete_hlasovani",
"prednasky", "prednasky",
"hlasovanioznalostech" "hlasovani"
],
[
"change_hlasovani",
"prednasky",
"hlasovani"
],
[
"view_hlasovani",
"prednasky",
"hlasovani"
], ],
[ [
"add_prednaska", "add_prednaska",
@ -264,12 +274,12 @@
"prednaska" "prednaska"
], ],
[ [
"change_prednaska", "delete_prednaska",
"prednasky", "prednasky",
"prednaska" "prednaska"
], ],
[ [
"delete_prednaska", "change_prednaska",
"prednasky", "prednasky",
"prednaska" "prednaska"
], ],
@ -284,12 +294,12 @@
"seznam" "seznam"
], ],
[ [
"change_seznam", "delete_seznam",
"prednasky", "prednasky",
"seznam" "seznam"
], ],
[ [
"delete_seznam", "change_seznam",
"prednasky", "prednasky",
"seznam" "seznam"
], ],
@ -298,38 +308,18 @@
"prednasky", "prednasky",
"seznam" "seznam"
], ],
[
"add_znalost",
"prednasky",
"znalost"
],
[
"change_znalost",
"prednasky",
"znalost"
],
[
"delete_znalost",
"prednasky",
"znalost"
],
[
"view_znalost",
"prednasky",
"znalost"
],
[ [
"add_konfera", "add_konfera",
"soustredeni", "soustredeni",
"konfera" "konfera"
], ],
[ [
"change_konfera", "delete_konfera",
"soustredeni", "soustredeni",
"konfera" "konfera"
], ],
[ [
"delete_konfera", "change_konfera",
"soustredeni", "soustredeni",
"konfera" "konfera"
], ],
@ -344,12 +334,12 @@
"konfery_ucastnici" "konfery_ucastnici"
], ],
[ [
"change_konfery_ucastnici", "delete_konfery_ucastnici",
"soustredeni", "soustredeni",
"konfery_ucastnici" "konfery_ucastnici"
], ],
[ [
"delete_konfery_ucastnici", "change_konfery_ucastnici",
"soustredeni", "soustredeni",
"konfery_ucastnici" "konfery_ucastnici"
], ],
@ -364,12 +354,12 @@
"soustredeni" "soustredeni"
], ],
[ [
"change_soustredeni", "delete_soustredeni",
"soustredeni", "soustredeni",
"soustredeni" "soustredeni"
], ],
[ [
"delete_soustredeni", "change_soustredeni",
"soustredeni", "soustredeni",
"soustredeni" "soustredeni"
], ],
@ -384,12 +374,12 @@
"soustredeni_organizatori" "soustredeni_organizatori"
], ],
[ [
"change_soustredeni_organizatori", "delete_soustredeni_organizatori",
"soustredeni", "soustredeni",
"soustredeni_organizatori" "soustredeni_organizatori"
], ],
[ [
"delete_soustredeni_organizatori", "change_soustredeni_organizatori",
"soustredeni", "soustredeni",
"soustredeni_organizatori" "soustredeni_organizatori"
], ],
@ -404,12 +394,12 @@
"soustredeni_ucastnici" "soustredeni_ucastnici"
], ],
[ [
"change_soustredeni_ucastnici", "delete_soustredeni_ucastnici",
"soustredeni", "soustredeni",
"soustredeni_ucastnici" "soustredeni_ucastnici"
], ],
[ [
"delete_soustredeni_ucastnici", "change_soustredeni_ucastnici",
"soustredeni", "soustredeni",
"soustredeni_ucastnici" "soustredeni_ucastnici"
], ],
@ -424,12 +414,12 @@
"tag" "tag"
], ],
[ [
"change_tag", "delete_tag",
"taggit", "taggit",
"tag" "tag"
], ],
[ [
"delete_tag", "change_tag",
"taggit", "taggit",
"tag" "tag"
], ],
@ -444,12 +434,12 @@
"taggeditem" "taggeditem"
], ],
[ [
"change_taggeditem", "delete_taggeditem",
"taggit", "taggit",
"taggeditem" "taggeditem"
], ],
[ [
"delete_taggeditem", "change_taggeditem",
"taggit", "taggit",
"taggeditem" "taggeditem"
], ],
@ -464,12 +454,12 @@
"cislo" "cislo"
], ],
[ [
"change_cislo", "delete_cislo",
"tvorba", "tvorba",
"cislo" "cislo"
], ],
[ [
"delete_cislo", "change_cislo",
"tvorba", "tvorba",
"cislo" "cislo"
], ],
@ -484,12 +474,12 @@
"clanek" "clanek"
], ],
[ [
"change_clanek", "delete_clanek",
"tvorba", "tvorba",
"clanek" "clanek"
], ],
[ [
"delete_clanek", "change_clanek",
"tvorba", "tvorba",
"clanek" "clanek"
], ],
@ -519,12 +509,12 @@
"pohadka" "pohadka"
], ],
[ [
"change_pohadka", "delete_pohadka",
"tvorba", "tvorba",
"pohadka" "pohadka"
], ],
[ [
"delete_pohadka", "change_pohadka",
"tvorba", "tvorba",
"pohadka" "pohadka"
], ],
@ -539,12 +529,12 @@
"problem" "problem"
], ],
[ [
"change_problem", "delete_problem",
"tvorba", "tvorba",
"problem" "problem"
], ],
[ [
"delete_problem", "change_problem",
"tvorba", "tvorba",
"problem" "problem"
], ],
@ -559,12 +549,12 @@
"rocnik" "rocnik"
], ],
[ [
"change_rocnik", "delete_rocnik",
"tvorba", "tvorba",
"rocnik" "rocnik"
], ],
[ [
"delete_rocnik", "change_rocnik",
"tvorba", "tvorba",
"rocnik" "rocnik"
], ],
@ -579,12 +569,12 @@
"tema" "tema"
], ],
[ [
"change_tema", "delete_tema",
"tvorba", "tvorba",
"tema" "tema"
], ],
[ [
"delete_tema", "change_tema",
"tvorba", "tvorba",
"tema" "tema"
], ],
@ -599,12 +589,12 @@
"uloha" "uloha"
], ],
[ [
"change_uloha", "delete_uloha",
"tvorba", "tvorba",
"uloha" "uloha"
], ],
[ [
"delete_uloha", "change_uloha",
"tvorba", "tvorba",
"uloha" "uloha"
], ],
@ -619,12 +609,12 @@
"nastaveni" "nastaveni"
], ],
[ [
"change_nastaveni", "delete_nastaveni",
"various", "various",
"nastaveni" "nastaveni"
], ],
[ [
"delete_nastaveni", "change_nastaveni",
"various", "various",
"nastaveni" "nastaveni"
], ],

View file

@ -57,7 +57,6 @@ DOBA_ODHLASENI_PRI_ZASKRTNUTI_NEODHLASOVAT = 365 * 24 * 3600 # rok
CSRF_FAILURE_VIEW = 'various.views.csrf.csrf_error' CSRF_FAILURE_VIEW = 'various.views.csrf.csrf_error'
# Modules configuration # Modules configuration
FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"
AUTHENTICATION_BACKENDS = ( AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend', 'django.contrib.auth.backends.ModelBackend',

View file

@ -4,7 +4,7 @@ from reversion.admin import VersionAdmin
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.html import escape from django.utils.html import escape
from .models import Prednaska, Seznam, Znalost from .models import Prednaska, Seznam, STAV_NAVRH
from soustredeni.models import Soustredeni from soustredeni.models import Soustredeni
@ -64,14 +64,14 @@ admin.site.register(Seznam, SeznamAdmin)
class PrednaskaAdmin(VersionAdmin): class PrednaskaAdmin(VersionAdmin):
list_display = ['nazev', 'org', 'obor'] list_display = ['nazev', 'org', 'obor']
list_filter = ['org', 'obor'] list_filter = ['org', 'obor']
search_fields = ['nazev'] search_fields = []
filter_horizontal = ('seznamy', ) filter_horizontal = ('seznamy', )
actions = ['move_to_soustredeni'] actions = ['move_to_soustredeni']
def move_to_soustredeni(self, request, queryset): def move_to_soustredeni(self, request, queryset):
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=STAV_NAVRH)
if len(seznam) == 0: if len(seznam) == 0:
self.message_user( self.message_user(
request, request,
@ -97,10 +97,3 @@ class PrednaskaAdmin(VersionAdmin):
admin.site.register(Prednaska, PrednaskaAdmin) admin.site.register(Prednaska, PrednaskaAdmin)
class ZnalostAdmin(PrednaskaAdmin): # Trochu hack, ať nemusím vypisovat všechno znovu
list_display = ("__str__",)
list_filter = ()
admin.site.register(Znalost, ZnalostAdmin)

View file

@ -1,15 +1,7 @@
from django import forms from django import forms
from .models import Hlasovani, HlasovaniOZnalostech class NewPrednaskyForm(forms.Form):
ucastnik = forms.CharField(label = 'Tvoje jméno', max_length = 100)
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)

View file

@ -1,39 +0,0 @@
# Generated by Django 4.2.16 on 2025-01-24 13:41
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', '0018_post_split_soustredeni'),
]
operations = [
migrations.CreateModel(
name='Znalost',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nazev', models.CharField(help_text='Např. Neuronové sítě', max_length=200, verbose_name='Nadpis')),
('text', models.TextField(blank=True, help_text='Např. Perceptron, vrstevnatá síť, forward a backward propagation', null=True, verbose_name='Detailní popis')),
('seznamy', models.ManyToManyField(to='prednasky.seznam')),
],
options={
'verbose_name': 'Znalost k přednáškám',
'verbose_name_plural': 'Znalosti k přednáškám',
'db_table': 'prednasky_znalost',
},
),
migrations.CreateModel(
name='HlasovaniOZnalostech',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('odpoved', models.CharField(choices=[(-1, 'Tohle celkem umím'), (0, 'Už jsem o tom slyšel, ale neřekl bychm, že to úplně umím'), (1, 'Tohle vůbec neznám')], max_length=16, verbose_name='odpověď')),
('seznam', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='prednasky.seznam')),
('ucastnik', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='personalni.osoba')),
('znalost', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='prednasky.znalost')),
],
),
]

View file

@ -1,105 +1,81 @@
from django.db import models from django.db import models
from soustredeni.models import Soustredeni from soustredeni.models import Soustredeni
from personalni.models import Organizator, Osoba from personalni.models import Organizator
STAV_NAVRH = 1
STAV_BUDE = 2
STAV_CHOICES = (
(STAV_NAVRH, 'Návrh'),
(STAV_BUDE, 'Bude')
)
class Seznam(models.Model): class Seznam(models.Model):
class Meta: class Meta:
db_table = "prednasky_seznam" db_table = 'prednasky_seznam'
verbose_name = "Seznam přednášek" verbose_name = 'Seznam přednášek'
verbose_name_plural = "Seznamy přednášek" verbose_name_plural = 'Seznamy přednášek'
ordering = ["soustredeni", "stav"] ordering = ['soustredeni', 'stav']
class Stav(models.IntegerChoices):
NAVRH = 1, "Návrh"
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,
stav = models.IntegerField("Stav", choices=Stav.choices, default=Stav.NAVRH) on_delete=models.PROTECT)
stav = models.IntegerField('Stav',choices=STAV_CHOICES,default = STAV_NAVRH)
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 "Seznam {}přednášek na {}".format("návrhů "
if self.stav == STAV_NAVRH else "", self.soustredeni)
CHOICES_OBTIZNOST = (
(1, 'Lehká'),
(2, 'Střední'),
(3, 'Těžká'),
)
CHOICES_BODY = (
(-1, '-1'),
(0, '0'),
(1, '1'),
)
class Prednaska(models.Model): class Prednaska(models.Model):
class Meta: class Meta:
db_table = "prednasky_prednaska" db_table = 'prednasky_prednaska'
verbose_name = "Přednáška" verbose_name = 'Přednáška'
verbose_name_plural = "Přednášky" verbose_name_plural = 'Přednášky'
ordering = ["org", "nazev"] ordering = ['org', 'nazev']
class Obtiznost(models.IntegerChoices):
LEHKA = 1, "Lehká"
STREDNI = 2, "Střední"
TEZKA = 3, "Těžká"
id = models.AutoField(primary_key = True) id = models.AutoField(primary_key = True)
nazev = models.CharField("Název", max_length=300) nazev = models.CharField('Název', max_length = 300)
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=CHOICES_OBTIZNOST)
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)
def __str__(self): def __str__(self):
return f"{self.nazev} ({self.org})" return "{} ({})".format(self.nazev, self.org)
class Hlasovani(models.Model): class Hlasovani(models.Model):
class Meta: class Meta:
db_table = "prednasky_hlasovani" db_table = 'prednasky_hlasovani'
verbose_name = "Hlasování" verbose_name = 'Hlasování'
verbose_name_plural = "Hlasování" verbose_name_plural = 'Hlasování'
ordering = ["ucastnik", "prednaska"] ordering = ['ucastnik', 'prednaska']
class Body(models.IntegerChoices):
NECHCI = -1, "rozhodně nechci"
JEDNO = 0, "je mi to jedno"
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)
body = models.IntegerField("Body", default=Body.JEDNO, choices=Body.choices) body = models.IntegerField('Body', default = 0, choices = CHOICES_BODY)
ucastnik = models.CharField('Účastník', max_length = 100)
# (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) seznam = models.ForeignKey(Seznam,null=True,on_delete=models.SET_NULL)
def __str__(self): def __str__(self):
return f"{self.ucastnik} dal {self.body} bodů {self.prednaska} v seznamu {self.seznam}" return "{} dal {} bodů {} v seznamu {}".format(self.ucastnik,
self.body, self.prednaska, self.seznam)
class Znalost(models.Model):
class Meta:
db_table = "prednasky_znalost"
verbose_name = "Znalost k přednáškám"
verbose_name_plural = "Znalosti k přednáškám"
nazev = models.CharField("Nadpis", max_length=200, blank=False, null=False, help_text="Např. Neuronové sítě")
text = models.TextField("Detailní popis", blank=True, null=True, help_text="Např. Perceptron, vrstevnatá síť, forward a backward propagation")
seznamy = models.ManyToManyField(Seznam)
def __str__(self):
return self.nazev
class HlasovaniOZnalostech(models.Model):
class Odpoved(models.IntegerChoices):
UMIM = -1, "Tohle celkem 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"
odpoved = models.CharField(u"odpověď", max_length=16, choices=Odpoved.choices, 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)
seznam = models.ForeignKey(Seznam, on_delete=models.SET_NULL, blank=True, null=True)
def __str__(self):
return f"{self.ucastnik} dal {self.znalost} bodů {self.znalost} v seznamu {self.seznam}"

View file

@ -5,36 +5,36 @@
{% block content %} {% block content %}
<h1>{% block nadpis1a %}Hlasování o přednáškách{% endblock %}</h1> <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>
<form enctype="multipart/form-data" action="." method="post"> <form enctype="multipart/form-data" action="." method="post">
{% csrf_token %} {% csrf_token %}
<table>
<h3>Jak moc by ses chtěl(a) zúčastnit následujících přednášek?</h3> {% for p, h in prednasky %}
<p>Obtížnost 1 je nejlehčí, 3 nejtěžší.</p> <tr><td><label>{{p.org}}: <span style="font-size: 175%">{{p.nazev}}</span></label></td></tr>
{{ form_set_prednasky.management_form }} <tr><td><p><i>{{p.anotace}}</i></p></td></tr>
{% for f, p in formy_a_prednasky %} <tr><td><label>Obor: </label> {{p.obor}}</td></tr>
<h4>{{p.nazev}} ({{p.org}})</h4> <tr><td><label>Obtížnost: </label> {{p.obtiznost}}</td> </tr>
<p class="textprednasky">{{p.anotace}}</p> {% if p.klicova %}<tr><td><label>Klíčová slova: </label> {{p.klicova}}</td></tr>{% endif%}
<label>Obor: </label> {{p.obor}}<br> <tr><td>Hodnocení:
<label>Obtížnost: </label> {{p.obtiznost}}<br> <INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="-1" {% if h == -1 %} CHECKED="checked" {% endif %} > rozhodně nechci
{% if p.klicova %}<label>Klíčová slova: </label> {{p.klicova}}<br>{% endif%} <INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="0" {% if h == 0 %} CHECKED="checked" {% endif %}> je mi to jedno
<br> <INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="1" {% if h == 1 %} CHECKED="checked" {% endif %}> rozhodně chci
{{ f }} </td></tr>
<br> <tr><td>&nbsp;</td></tr>
{% 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 %}
<tr><td><input name="odeslat" type="submit" value="Odeslat"></td><tr>
{{ form_set_znalosti.management_form }} </table>
{% 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> </form>
{% endblock %} {% endblock %}

View file

@ -14,7 +14,7 @@
{% else %} {% else %}
<a href="/prednasky/seznam_prednasek/{{seznam.id}}">Seznam přednášek na soustředění {{seznam.soustredeni.misto}} </a> <a href="/prednasky/seznam_prednasek/{{seznam.id}}">Seznam přednášek na soustředění {{seznam.soustredeni.misto}} </a>
{% endif %} {% endif %}
<a href="/prednasky/seznam_prednasek/{{seznam.id}}/hlasovani.csv">Export</a> <a href="/prednasky/seznam_prednasek/{{seznam.id}}/export">Export</a>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>

View file

@ -12,15 +12,10 @@ 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>/export',
org_required(views.PrednaskyExportView), org_required(views.SeznamExportView),
name='seznam-export-csv' name='seznam-export'
), ),
path( path(
'prednasky/seznam_prednasek/<int:seznam>/', 'prednasky/seznam_prednasek/<int:seznam>/',

View file

@ -1,112 +1,65 @@
import csv
import http import http
import logging
from django.http import HttpResponse
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
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction from django.db.models import Sum
from django.forms import Form
from various.views.pomocne import formularOKView from various.views.pomocne import formularOKView
from .forms import HlasovaniPrednaskaFormSet, HlasovaniZnalostiFormSet
from various.models import Nastaveni from various.models import Nastaveni
from prednasky.models import Prednaska, Hlasovani, Znalost, HlasovaniOZnalostech, Seznam from prednasky.models import Prednaska, Hlasovani, Seznam, STAV_NAVRH
from soustredeni.models import Soustredeni from soustredeni.models import Soustredeni
from personalni.models import Osoba from personalni.models import Osoba
PREDNASKY_PREFIX = "prednasky"
ZNALOSTI_PREFIX = "znalosti"
logger = logging.getLogger(__name__)
def newPrednaska(request): def newPrednaska(request):
# 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 = STAV_NAVRH).first()
if sous is None or seznam is None: if sous is None or seznam is None:
return render(request, 'universal.html', { return render(request, 'universal.html', {
'title': "Nelze hlasovat", 'title': "Nelze hlasovat",
'text': "Není žádný seznam přednášek, o kterém by se dalo hlasovat.", 'text': "Není žádný seznam přednášek, o kterém by se dalo hlasovat.",
}, status=http.HTTPStatus.NOT_FOUND) }, status=http.HTTPStatus.NOT_FOUND)
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)
# obsluha formulare
if request.method == 'POST': if request.method == 'POST':
form_set_prednasky = HlasovaniPrednaskaFormSet(request.POST, prefix=PREDNASKY_PREFIX) form = Form(request.POST, request.FILES)
form_set_znalosti = HlasovaniZnalostiFormSet(request.POST, prefix=ZNALOSTI_PREFIX) 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
if form_set_prednasky.is_valid() and form_set_znalosti.is_valid(): # TODO v následujících řádcích je zbytečně mnoho dotazů na QuerySet (pokud účastník hlasoval, hlasoval u všech)
with transaction.atomic(): for i in request.POST:
seznam.hlasovani_set.filter(ucastnik=ucastnik).delete() if i[0] == 'q':
seznam.hlasovanioznalostech_set.filter(ucastnik=osoba).delete() prednaska = Prednaska.objects.filter(pk=int(i[1:]))[0]
hlasovani = Hlasovani.objects.filter(ucastnik=ucastnik, prednaska=prednaska).first()
for form in form_set_prednasky: if not hlasovani:
prednaska_id = form.cleaned_data['prednaska_id'] hlasovani = Hlasovani()
prednaska = Prednaska.objects.filter(id=prednaska_id).first() hlasovani.prednaska = prednaska
if prednaska is None: hlasovani.ucastnik = ucastnik
logger.error(f"Účastník {ucastnik} hodnotil neexistující přednášku {prednaska_id} číslem {form.cleaned_data['body']}") hlasovani.seznam = seznam
continue hlasovani.body = int(request.POST[i])
hlasovani.save()
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') return HttpResponseRedirect('./hotovo')
def prednaska_hodnoceni(prednaska):
h = Hlasovani.objects.filter(ucastnik=ucastnik, prednaska=prednaska).first()
if h:
return prednaska, h.body
else: else:
prednasky = seznam.prednaska_set.all() return prednaska, 0
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( return render(
request, request,
'prednasky/base.html', '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),
}
) )
@ -134,7 +87,7 @@ class SeznamListView(generic.ListView):
# hlasovani se vztahuje k nejnovejsimu soustredeni # hlasovani se vztahuje k nejnovejsimu soustredeni
sous = Soustredeni.objects.first() sous = Soustredeni.objects.first()
seznam = Seznam.objects.filter(soustredeni = sous, stav=Seznam.Stav.NAVRH).first() seznam = Seznam.objects.filter(soustredeni = sous, stav = STAV_NAVRH).first()
for obj in self.object_list: for obj in self.object_list:
hlasovani_set = obj.hlasovani_set.filter(seznam=seznam).only('body') hlasovani_set = obj.hlasovani_set.filter(seznam=seznam).only('body')
@ -143,76 +96,32 @@ class SeznamListView(generic.ListView):
return context return context
# def SeznamExportView(request, seznam): def SeznamExportView(request, seznam):
# """Vypíše výsledky hlasování ve formátu pro prologovský optimalizátor""" """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 # TODO zřejmě se nepoužívá, časem vyřadit? nahradit tabulkou vhodnější pro
# # lidi? # lidi?
# hlasovani = Hlasovani.objects.filter(seznam=seznam) hlasovani = Hlasovani.objects.filter(seznam=seznam)
# prednasky = Prednaska.objects.filter(seznamy=seznam) prednasky = Prednaska.objects.filter(seznamy=seznam)
# orgove = set(p.org for p in prednasky) orgove = set(p.org for p in prednasky)
# ucastnici = set(h.ucastnik for h in hlasovani) 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"
# )
for p in prednasky:
def PrednaskyExportView(request, seznam: int, **kwargs): p.body = []
hlasovani = Hlasovani.objects.filter(seznam=seznam).select_related("prednaska") for u in ucastnici:
hlasovani_o_znalostech = HlasovaniOZnalostech.objects.filter(seznam=seznam).select_related('ucastnik', 'znalost') try:
p.body.append(hlasovani.get(ucastnik=u, prednaska=p).body)
prednasky = list(Prednaska.objects.filter(seznamy=seznam)) except ObjectDoesNotExist:
znalosti = list(Znalost.objects.filter(seznamy=seznam)) # účastník nehlasoval
p.body.append("?")
prednasky_map: dict[int, int] = {p.id: i for i, p in enumerate(prednasky, 1)}
offset = len(prednasky_map)
znalosti_map: dict[int, int] = {z.id: i for i, z in enumerate(znalosti, offset + 1)}
width = offset + len(znalosti_map)
table: [str, list[str|Prednaska|Znalost,]] = {}
for h in hlasovani: for h in hlasovani:
if h.ucastnik not in table: h.ucastnik = hash(h.ucastnik)
table[h.ucastnik] = [h.ucastnik] + ([""] * width)
if h.prednaska.id in prednasky_map: return render(
table[h.ucastnik][prednasky_map[h.prednaska.id]] = h.body request,
else: 'prednasky/seznam_prednasek_export.txt',
pass # Padat hlasitě? {"hlasovani": hlasovani, "prednasky": prednasky, "orgove": orgove},
content_type="text/plain"
for h in hlasovani_o_znalostech: )
ucastnik = str(h.ucastnik) + ' ' + str(h.ucastnik.id) # id, kvůli kolizi jmen
if ucastnik not in table:
table[ucastnik] = [ucastnik] + ([""] * width)
if h.znalost.id in znalosti_map:
table[ucastnik][znalosti_map[h.znalost.id]] = h.odpoved
else:
pass # Padat hlasitě?
response = HttpResponse(content_type="text/csv", charset="utf-8")
response["Content-Disposition"] = 'attachment; filename="hlasovani.csv"'
writer = csv.writer(response)
writer.writerow(["jména \\ přednáška|znalost"] + list(map(str, prednasky + znalosti)))
for row in table.values():
writer.writerow(list(map(str, row)))
return response