Move soustredeni do aplikace soustredeni
This commit is contained in:
parent
0cd1c3ef1a
commit
1b3a04be14
18 changed files with 364 additions and 310 deletions
|
@ -141,6 +141,7 @@ INSTALLED_APPS = (
|
||||||
'odevzdavatko',
|
'odevzdavatko',
|
||||||
'vysledkovky',
|
'vysledkovky',
|
||||||
'personalni',
|
'personalni',
|
||||||
|
'soustredeni',
|
||||||
|
|
||||||
# Admin upravy:
|
# Admin upravy:
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,13 @@ urlpatterns = [
|
||||||
|
|
||||||
# Korekturovaci aplikace (ma vlastni podadresare)
|
# Korekturovaci aplikace (ma vlastni podadresare)
|
||||||
path('', include('korektury.urls')),
|
path('', include('korektury.urls')),
|
||||||
|
|
||||||
# Prednaskova aplikace (ma vlastni podadresare)
|
# Prednaskova aplikace (ma vlastni podadresare)
|
||||||
path('', include('prednasky.urls')),
|
path('', include('prednasky.urls')),
|
||||||
|
|
||||||
|
# Soustredkova aplikace (ma vlastni podadresare)
|
||||||
|
path('', include('soustredeni.urls')),
|
||||||
|
|
||||||
# Personalni aplikace (ma vlastni podadresare)
|
# Personalni aplikace (ma vlastni podadresare)
|
||||||
# (profil, osobní údaje, ..., ne autentizace, viz dále)
|
# (profil, osobní údaje, ..., ne autentizace, viz dále)
|
||||||
path('', include('personalni.urls')),
|
path('', include('personalni.urls')),
|
||||||
|
|
|
@ -150,41 +150,6 @@ class ResitelInline(admin.TabularInline):
|
||||||
model = m.Resitel
|
model = m.Resitel
|
||||||
extra = 1
|
extra = 1
|
||||||
|
|
||||||
class SoustredeniUcastniciInline(admin.TabularInline):
|
|
||||||
model = m.Soustredeni_Ucastnici
|
|
||||||
extra = 1
|
|
||||||
fields = ['resitel','poznamka']
|
|
||||||
autocomplete_fields = ['resitel']
|
|
||||||
ordering = ['resitel__osoba__jmeno', 'resitel__osoba__prijmeni']
|
|
||||||
formfield_overrides = {
|
|
||||||
models.TextField: {'widget': widgets.TextInput}
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_queryset(self,request):
|
|
||||||
qs = super().get_queryset(request)
|
|
||||||
return qs.select_related('resitel','soustredeni')
|
|
||||||
|
|
||||||
class SoustredeniOrganizatoriInline(admin.TabularInline):
|
|
||||||
model = m.Soustredeni.organizatori.through
|
|
||||||
extra = 1
|
|
||||||
fields = ['organizator','poznamka']
|
|
||||||
autocomplete_fields = ['organizator']
|
|
||||||
ordering = ['organizator__osoba__jmeno','organizator__prijmeni']
|
|
||||||
formfield_overrides = {
|
|
||||||
models.TextField: {'widget': widgets.TextInput}
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_queryset(self,request):
|
|
||||||
qs = super().get_queryset(request)
|
|
||||||
return qs.select_related('organizator', 'soustredeni')
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(m.Soustredeni)
|
|
||||||
class SoustredeniAdmin(admin.ModelAdmin):
|
|
||||||
model = m.Soustredeni
|
|
||||||
inline_type = 'tabular'
|
|
||||||
inlines = [SoustredeniUcastniciInline, SoustredeniOrganizatoriInline]
|
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(m.Pohadka)
|
admin.site.register(m.Pohadka)
|
||||||
admin.site.register(m.Obrazek)
|
admin.site.register(m.Obrazek)
|
||||||
|
|
|
@ -2,3 +2,4 @@ from .models_all import *
|
||||||
from .odevzdavatko import *
|
from .odevzdavatko import *
|
||||||
from .base import *
|
from .base import *
|
||||||
from .personalni import *
|
from .personalni import *
|
||||||
|
from .soustredeni import *
|
||||||
|
|
|
@ -317,68 +317,6 @@ class Cislo(SeminarModelBase):
|
||||||
raise ValidationError({'datum_deadline_soustredeni': "Soustřeďkový deadline musí předcházet finálnímu deadlinu"})
|
raise ValidationError({'datum_deadline_soustredeni': "Soustřeďkový deadline musí předcházet finálnímu deadlinu"})
|
||||||
|
|
||||||
|
|
||||||
@reversion.register(ignore_duplicates=True)
|
|
||||||
class Soustredeni(SeminarModelBase):
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
db_table = 'seminar_soustredeni'
|
|
||||||
verbose_name = 'Soustředění'
|
|
||||||
verbose_name_plural = 'Soustředění'
|
|
||||||
ordering = ['-rocnik__rocnik', '-datum_zacatku']
|
|
||||||
|
|
||||||
# Interní ID
|
|
||||||
id = models.AutoField(primary_key = True)
|
|
||||||
|
|
||||||
rocnik = models.ForeignKey(Rocnik, verbose_name='ročník', related_name='soustredeni',
|
|
||||||
on_delete=models.PROTECT)
|
|
||||||
|
|
||||||
datum_zacatku = models.DateField('datum začátku', blank=True, null=True,
|
|
||||||
help_text='První den soustředění')
|
|
||||||
|
|
||||||
datum_konce = models.DateField('datum konce', blank=True, null=True,
|
|
||||||
help_text='Poslední den soustředění')
|
|
||||||
|
|
||||||
verejne_db = models.BooleanField('soustředění zveřejněno', db_column='verejne', default=False)
|
|
||||||
|
|
||||||
misto = models.CharField('místo soustředění', max_length=256, blank=True, default='',
|
|
||||||
help_text='Místo (název obce, volitelně též objektu')
|
|
||||||
|
|
||||||
ucastnici = models.ManyToManyField(pm.Resitel, verbose_name='účastníci soustředění',
|
|
||||||
help_text='Seznam účastníků soustředění', through='Soustredeni_Ucastnici')
|
|
||||||
|
|
||||||
organizatori = models.ManyToManyField(pm.Organizator,
|
|
||||||
verbose_name='Organizátoři soustředění',
|
|
||||||
help_text='Seznam organizátorů soustředění',
|
|
||||||
through='Soustredeni_Organizatori')
|
|
||||||
|
|
||||||
text = models.TextField('text k soustředění (HTML)', blank=True, default='')
|
|
||||||
|
|
||||||
TYP_JARNI = 'jarni'
|
|
||||||
TYP_PODZIMNI = 'podzimni'
|
|
||||||
TYP_VIKEND = 'vikend'
|
|
||||||
TYP_CHOICES = [
|
|
||||||
(TYP_JARNI, 'Jarní soustředění'),
|
|
||||||
(TYP_PODZIMNI, 'Podzimní soustředění'),
|
|
||||||
(TYP_VIKEND, 'Víkendový sraz'),
|
|
||||||
]
|
|
||||||
typ = models.CharField('typ akce', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_PODZIMNI)
|
|
||||||
|
|
||||||
exportovat = models.BooleanField('export do AESOPa', db_column='exportovat', default=False,
|
|
||||||
help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)')
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return '{} ({})'.format(self.misto, self.datum_zacatku)
|
|
||||||
|
|
||||||
def verejne(self):
|
|
||||||
return self.verejne_db
|
|
||||||
verejne.boolean = True
|
|
||||||
|
|
||||||
def verejne_url(self):
|
|
||||||
#return reverse('seminar_soustredeni', kwargs={'pk': self.id})
|
|
||||||
return reverse('seminar_seznam_soustredeni')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@reversion.register(ignore_duplicates=True)
|
@reversion.register(ignore_duplicates=True)
|
||||||
# Pozor na následující řádek. *Nekrmit, asi kouše!*
|
# Pozor na následující řádek. *Nekrmit, asi kouše!*
|
||||||
class Problem(SeminarModelBase,PolymorphicModel):
|
class Problem(SeminarModelBase,PolymorphicModel):
|
||||||
|
@ -658,20 +596,6 @@ def aux_generate_filename(self, filename):
|
||||||
clean)
|
clean)
|
||||||
return os.path.join(datedir, fname)
|
return os.path.join(datedir, fname)
|
||||||
|
|
||||||
# Django neumí jednoduše serializovat partial nebo třídu s __call__
|
|
||||||
# (https://docs.djangoproject.com/en/1.8/topics/migrations/),
|
|
||||||
# neprojdou pak migrace. Takže rozlišení funkcí generujících názvy souboru
|
|
||||||
# podle adresáře řešíme takto.
|
|
||||||
|
|
||||||
##
|
|
||||||
def generate_filename_konfera(self, filename):
|
|
||||||
return os.path.join(
|
|
||||||
settings.SEMINAR_KONFERY_DIR,
|
|
||||||
aux_generate_filename(self, filename)
|
|
||||||
)
|
|
||||||
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
class Pohadka(SeminarModelBase):
|
class Pohadka(SeminarModelBase):
|
||||||
"""Kus pohádky před/za úlohou v čísle"""
|
"""Kus pohádky před/za úlohou v čísle"""
|
||||||
|
@ -718,124 +642,6 @@ class Pohadka(SeminarModelBase):
|
||||||
# Neexistující *Node nemá smysl aktualizovat.
|
# Neexistující *Node nemá smysl aktualizovat.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@reversion.register(ignore_duplicates=True)
|
|
||||||
class Soustredeni_Ucastnici(SeminarModelBase):
|
|
||||||
# zmena dedicnosti z models.Model na SeminarModelBase, potencialni vznik bugu
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
db_table = 'seminar_soustredeni_ucastnici'
|
|
||||||
verbose_name = 'Účast na soustředění'
|
|
||||||
verbose_name_plural = 'Účasti na soustředění'
|
|
||||||
ordering = ['soustredeni', 'resitel']
|
|
||||||
|
|
||||||
# Interní ID
|
|
||||||
id = models.AutoField(primary_key = True)
|
|
||||||
|
|
||||||
resitel = models.ForeignKey(pm.Resitel, verbose_name='řešitel', on_delete=models.PROTECT)
|
|
||||||
|
|
||||||
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
|
||||||
on_delete=models.PROTECT)
|
|
||||||
|
|
||||||
poznamka = models.TextField('neveřejná poznámka', blank=True,
|
|
||||||
help_text='Neveřejná poznámka k účasti (plain text)')
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return '{} na {}'.format(self.resitel, self.soustredeni)
|
|
||||||
# NOTE: Poteciální DB HOG bez select_related
|
|
||||||
|
|
||||||
@reversion.register(ignore_duplicates=True)
|
|
||||||
class Soustredeni_Organizatori(SeminarModelBase):
|
|
||||||
# zmena dedicnosti z models.Model na SeminarModelBase, potencialni vznik bugu
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
db_table = 'seminar_soustredeni_organizatori'
|
|
||||||
verbose_name = 'Účast organizátorů na soustředění'
|
|
||||||
verbose_name_plural = 'Účasti organizátorů na soustředění'
|
|
||||||
ordering = ['soustredeni', 'organizator']
|
|
||||||
|
|
||||||
# Interní ID
|
|
||||||
id = models.AutoField(primary_key = True)
|
|
||||||
|
|
||||||
organizator = models.ForeignKey(pm.Organizator, verbose_name='organizátor',
|
|
||||||
on_delete=models.PROTECT)
|
|
||||||
|
|
||||||
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
|
||||||
on_delete=models.PROTECT)
|
|
||||||
|
|
||||||
poznamka = models.TextField('neveřejná poznámka', blank=True,
|
|
||||||
help_text='Neveřejná poznámka k účasti organizátora (plain text)')
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return '{} na {}'.format(self.organizator, self.soustredeni)
|
|
||||||
# NOTE: Poteciální DB HOG bez select_related
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@reversion.register(ignore_duplicates=True)
|
|
||||||
class Konfera(Problem):
|
|
||||||
class Meta:
|
|
||||||
db_table = 'seminar_konfera'
|
|
||||||
verbose_name = 'Konfera'
|
|
||||||
verbose_name_plural = 'Konfery'
|
|
||||||
|
|
||||||
anotace = models.TextField('anotace', blank=True,
|
|
||||||
help_text='Popis, o čem bude konfera.')
|
|
||||||
|
|
||||||
abstrakt = models.TextField('abstrakt', blank=True,
|
|
||||||
help_text='Abstrakt konfery tak, jak byl uveden ve sborníku')
|
|
||||||
|
|
||||||
# FIXME: Umíme omezit jen na účastníky daného soustřeďka?
|
|
||||||
ucastnici = models.ManyToManyField(pm.Resitel, verbose_name='účastníci konfery',
|
|
||||||
help_text='Seznam účastníků konfery', through='Konfery_Ucastnici')
|
|
||||||
|
|
||||||
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
|
||||||
related_name='konfery', on_delete = models.SET_NULL, null=True)
|
|
||||||
|
|
||||||
TYP_VELETRH = 'veletrh'
|
|
||||||
TYP_PREZENTACE = 'prezentace'
|
|
||||||
TYP_CHOICES = [
|
|
||||||
(TYP_VELETRH, 'Veletrh (postery)'),
|
|
||||||
(TYP_PREZENTACE, 'Prezentace (přednáška)'),
|
|
||||||
]
|
|
||||||
typ_prezentace = models.CharField('typ prezentace', max_length=16, choices=TYP_CHOICES,
|
|
||||||
blank=False, default=TYP_VELETRH)
|
|
||||||
|
|
||||||
prezentace = models.FileField('prezentace',help_text = 'Prezentace nebo fotka posteru',
|
|
||||||
upload_to = generate_filename_konfera, blank=True)
|
|
||||||
|
|
||||||
materialy = models.FileField('materialy',
|
|
||||||
help_text = 'Další materiály ke konfeře zabalené do jednoho souboru',
|
|
||||||
upload_to = generate_filename_konfera, blank=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "{}: ({})".format(self.nazev, self.soustredeni)
|
|
||||||
|
|
||||||
def cislo_node(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
@reversion.register(ignore_duplicates=True)
|
|
||||||
class Konfery_Ucastnici(models.Model):
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
db_table = 'seminar_konfery_ucastnici'
|
|
||||||
verbose_name = 'Účast na konfeře'
|
|
||||||
verbose_name_plural = 'Účasti na konfeře'
|
|
||||||
ordering = ['konfera', 'resitel']
|
|
||||||
|
|
||||||
# Interní ID
|
|
||||||
id = models.AutoField(primary_key = True)
|
|
||||||
|
|
||||||
resitel = models.ForeignKey(pm.Resitel, verbose_name='řešitel', on_delete=models.PROTECT)
|
|
||||||
|
|
||||||
konfera = models.ForeignKey(Konfera, verbose_name='konfera', on_delete=models.CASCADE)
|
|
||||||
|
|
||||||
poznamka = models.TextField('neveřejná poznámka', blank=True,
|
|
||||||
help_text='Neveřejná poznámka k účasti (plain text)')
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return '{} na {}'.format(self.resitel, self.konfera)
|
|
||||||
# NOTE: Poteciální DB HOG bez select_related
|
|
||||||
|
|
||||||
class Obrazek(SeminarModelBase):
|
class Obrazek(SeminarModelBase):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
214
seminar/models/soustredeni.py
Normal file
214
seminar/models/soustredeni.py
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
from django.urls import reverse
|
||||||
|
from reversion import revisions as reversion
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
from . import personalni as pm
|
||||||
|
|
||||||
|
from .base import SeminarModelBase
|
||||||
|
from seminar.models import models_all as am
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@reversion.register(ignore_duplicates=True)
|
||||||
|
class Soustredeni(SeminarModelBase):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'seminar_soustredeni'
|
||||||
|
verbose_name = 'Soustředění'
|
||||||
|
verbose_name_plural = 'Soustředění'
|
||||||
|
ordering = ['-rocnik__rocnik', '-datum_zacatku']
|
||||||
|
|
||||||
|
# Interní ID
|
||||||
|
id = models.AutoField(primary_key = True)
|
||||||
|
|
||||||
|
rocnik = models.ForeignKey(am.Rocnik, verbose_name='ročník', related_name='soustredeni',
|
||||||
|
on_delete=models.PROTECT)
|
||||||
|
|
||||||
|
datum_zacatku = models.DateField('datum začátku', blank=True, null=True,
|
||||||
|
help_text='První den soustředění')
|
||||||
|
|
||||||
|
datum_konce = models.DateField('datum konce', blank=True, null=True,
|
||||||
|
help_text='Poslední den soustředění')
|
||||||
|
|
||||||
|
verejne_db = models.BooleanField('soustředění zveřejněno', db_column='verejne', default=False)
|
||||||
|
|
||||||
|
misto = models.CharField('místo soustředění', max_length=256, blank=True, default='',
|
||||||
|
help_text='Místo (název obce, volitelně též objektu')
|
||||||
|
|
||||||
|
ucastnici = models.ManyToManyField(pm.Resitel, verbose_name='účastníci soustředění',
|
||||||
|
help_text='Seznam účastníků soustředění', through='Soustredeni_Ucastnici')
|
||||||
|
|
||||||
|
organizatori = models.ManyToManyField(pm.Organizator,
|
||||||
|
verbose_name='Organizátoři soustředění',
|
||||||
|
help_text='Seznam organizátorů soustředění',
|
||||||
|
through='Soustredeni_Organizatori')
|
||||||
|
|
||||||
|
text = models.TextField('text k soustředění (HTML)', blank=True, default='')
|
||||||
|
|
||||||
|
TYP_JARNI = 'jarni'
|
||||||
|
TYP_PODZIMNI = 'podzimni'
|
||||||
|
TYP_VIKEND = 'vikend'
|
||||||
|
TYP_CHOICES = [
|
||||||
|
(TYP_JARNI, 'Jarní soustředění'),
|
||||||
|
(TYP_PODZIMNI, 'Podzimní soustředění'),
|
||||||
|
(TYP_VIKEND, 'Víkendový sraz'),
|
||||||
|
]
|
||||||
|
typ = models.CharField('typ akce', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_PODZIMNI)
|
||||||
|
|
||||||
|
exportovat = models.BooleanField('export do AESOPa', db_column='exportovat', default=False,
|
||||||
|
help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} ({})'.format(self.misto, self.datum_zacatku)
|
||||||
|
|
||||||
|
def verejne(self):
|
||||||
|
return self.verejne_db
|
||||||
|
verejne.boolean = True
|
||||||
|
|
||||||
|
def verejne_url(self):
|
||||||
|
#return reverse('seminar_soustredeni', kwargs={'pk': self.id})
|
||||||
|
return reverse('seminar_seznam_soustredeni')
|
||||||
|
|
||||||
|
|
||||||
|
@reversion.register(ignore_duplicates=True)
|
||||||
|
class Soustredeni_Ucastnici(SeminarModelBase):
|
||||||
|
# zmena dedicnosti z models.Model na SeminarModelBase, potencialni vznik bugu
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'seminar_soustredeni_ucastnici'
|
||||||
|
verbose_name = 'Účast na soustředění'
|
||||||
|
verbose_name_plural = 'Účasti na soustředění'
|
||||||
|
ordering = ['soustredeni', 'resitel']
|
||||||
|
|
||||||
|
# Interní ID
|
||||||
|
id = models.AutoField(primary_key = True)
|
||||||
|
|
||||||
|
resitel = models.ForeignKey(pm.Resitel, verbose_name='řešitel', on_delete=models.PROTECT)
|
||||||
|
|
||||||
|
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
||||||
|
on_delete=models.PROTECT)
|
||||||
|
|
||||||
|
poznamka = models.TextField('neveřejná poznámka', blank=True,
|
||||||
|
help_text='Neveřejná poznámka k účasti (plain text)')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} na {}'.format(self.resitel, self.soustredeni)
|
||||||
|
# NOTE: Poteciální DB HOG bez select_related
|
||||||
|
|
||||||
|
|
||||||
|
@reversion.register(ignore_duplicates=True)
|
||||||
|
class Soustredeni_Organizatori(SeminarModelBase):
|
||||||
|
# zmena dedicnosti z models.Model na SeminarModelBase, potencialni vznik bugu
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'seminar_soustredeni_organizatori'
|
||||||
|
verbose_name = 'Účast organizátorů na soustředění'
|
||||||
|
verbose_name_plural = 'Účasti organizátorů na soustředění'
|
||||||
|
ordering = ['soustredeni', 'organizator']
|
||||||
|
|
||||||
|
# Interní ID
|
||||||
|
id = models.AutoField(primary_key = True)
|
||||||
|
|
||||||
|
organizator = models.ForeignKey(pm.Organizator, verbose_name='organizátor',
|
||||||
|
on_delete=models.PROTECT)
|
||||||
|
|
||||||
|
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
||||||
|
on_delete=models.PROTECT)
|
||||||
|
|
||||||
|
poznamka = models.TextField('neveřejná poznámka', blank=True,
|
||||||
|
help_text='Neveřejná poznámka k účasti organizátora (plain text)')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} na {}'.format(self.organizator, self.soustredeni)
|
||||||
|
# NOTE: Poteciální DB HOG bez select_related
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME cycle import
|
||||||
|
|
||||||
|
|
||||||
|
# Django neumí jednoduše serializovat partial nebo třídu s __call__
|
||||||
|
# (https://docs.djangoproject.com/en/1.8/topics/migrations/),
|
||||||
|
# neprojdou pak migrace. Takže rozlišení funkcí generujících názvy souboru
|
||||||
|
# podle adresáře řešíme takto.
|
||||||
|
|
||||||
|
##
|
||||||
|
def generate_filename_konfera(self, filename):
|
||||||
|
return os.path.join(
|
||||||
|
settings.SEMINAR_KONFERY_DIR,
|
||||||
|
am.aux_generate_filename(self, filename)
|
||||||
|
)
|
||||||
|
|
||||||
|
##
|
||||||
|
|
||||||
|
@reversion.register(ignore_duplicates=True)
|
||||||
|
class Konfera(am.Problem):
|
||||||
|
class Meta:
|
||||||
|
db_table = 'seminar_konfera'
|
||||||
|
verbose_name = 'Konfera'
|
||||||
|
verbose_name_plural = 'Konfery'
|
||||||
|
|
||||||
|
anotace = models.TextField('anotace', blank=True,
|
||||||
|
help_text='Popis, o čem bude konfera.')
|
||||||
|
|
||||||
|
abstrakt = models.TextField('abstrakt', blank=True,
|
||||||
|
help_text='Abstrakt konfery tak, jak byl uveden ve sborníku')
|
||||||
|
|
||||||
|
# FIXME: Umíme omezit jen na účastníky daného soustřeďka?
|
||||||
|
ucastnici = models.ManyToManyField(pm.Resitel, verbose_name='účastníci konfery',
|
||||||
|
help_text='Seznam účastníků konfery', through='Konfery_Ucastnici')
|
||||||
|
|
||||||
|
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
||||||
|
related_name='konfery', on_delete = models.SET_NULL, null=True)
|
||||||
|
|
||||||
|
TYP_VELETRH = 'veletrh'
|
||||||
|
TYP_PREZENTACE = 'prezentace'
|
||||||
|
TYP_CHOICES = [
|
||||||
|
(TYP_VELETRH, 'Veletrh (postery)'),
|
||||||
|
(TYP_PREZENTACE, 'Prezentace (přednáška)'),
|
||||||
|
]
|
||||||
|
typ_prezentace = models.CharField('typ prezentace', max_length=16, choices=TYP_CHOICES,
|
||||||
|
blank=False, default=TYP_VELETRH)
|
||||||
|
|
||||||
|
prezentace = models.FileField('prezentace',help_text = 'Prezentace nebo fotka posteru',
|
||||||
|
upload_to = generate_filename_konfera, blank=True)
|
||||||
|
|
||||||
|
materialy = models.FileField('materialy',
|
||||||
|
help_text = 'Další materiály ke konfeře zabalené do jednoho souboru',
|
||||||
|
upload_to = generate_filename_konfera, blank=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "{}: ({})".format(self.nazev, self.soustredeni)
|
||||||
|
|
||||||
|
def cislo_node(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@reversion.register(ignore_duplicates=True)
|
||||||
|
class Konfery_Ucastnici(models.Model):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'seminar_konfery_ucastnici'
|
||||||
|
verbose_name = 'Účast na konfeře'
|
||||||
|
verbose_name_plural = 'Účasti na konfeře'
|
||||||
|
ordering = ['konfera', 'resitel']
|
||||||
|
|
||||||
|
# Interní ID
|
||||||
|
id = models.AutoField(primary_key = True)
|
||||||
|
|
||||||
|
resitel = models.ForeignKey(pm.Resitel, verbose_name='řešitel', on_delete=models.PROTECT)
|
||||||
|
|
||||||
|
konfera = models.ForeignKey(Konfera, verbose_name='konfera', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
poznamka = models.TextField('neveřejná poznámka', blank=True,
|
||||||
|
help_text='Neveřejná poznámka k účasti (plain text)')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} na {}'.format(self.resitel, self.konfera)
|
||||||
|
# NOTE: Poteciální DB HOG bez select_related
|
|
@ -28,32 +28,6 @@ urlpatterns = [
|
||||||
#path('treenode/sirotcinec/', views.SirotcinecView.as_view(), name='seminar_treenode_sirotcinec'),
|
#path('treenode/sirotcinec/', views.SirotcinecView.as_view(), name='seminar_treenode_sirotcinec'),
|
||||||
#path('problem/(?P<pk>\d+)/(?P<prispevek>\d+)/', views.PrispevekView.as_view(), name='seminar_problem_prispevek'),
|
#path('problem/(?P<pk>\d+)/(?P<prispevek>\d+)/', views.PrispevekView.as_view(), name='seminar_problem_prispevek'),
|
||||||
|
|
||||||
# Soustredeni
|
|
||||||
path(
|
|
||||||
'soustredeni/probehlo/',
|
|
||||||
views.SoustredeniListView.as_view(),
|
|
||||||
name='seminar_seznam_soustredeni'
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'soustredeni/<int:soustredeni>/seznam_ucastniku',
|
|
||||||
org_required(views.SoustredeniUcastniciView.as_view()),
|
|
||||||
name='soustredeni_ucastnici'
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'soustredeni/<int:soustredeni>/maily_ucastniku',
|
|
||||||
org_required(views.SoustredeniMailyUcastnikuView.as_view()),
|
|
||||||
name='maily_ucastniku'
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'soustredeni/<int:soustredeni>/export_ucastniku',
|
|
||||||
org_required(views.soustredeniUcastniciExportView),
|
|
||||||
name='soustredeni_ucastnici_export'
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'soustredeni/<int:soustredeni>/fotogalerie/',
|
|
||||||
include('galerie.urls')
|
|
||||||
),
|
|
||||||
|
|
||||||
# Zadani
|
# Zadani
|
||||||
# path('aktualni/zadani/', views.AktualniZadaniView.as_view(), name='seminar_aktualni_zadani'), # Dočasně ad-hoc jednoduchá věc.
|
# path('aktualni/zadani/', views.AktualniZadaniView.as_view(), name='seminar_aktualni_zadani'), # Dočasně ad-hoc jednoduchá věc.
|
||||||
path('aktualni/zadani/', views.AktualniZadaniView, name='seminar_aktualni_zadani'),
|
path('aktualni/zadani/', views.AktualniZadaniView, name='seminar_aktualni_zadani'),
|
||||||
|
@ -101,11 +75,6 @@ urlpatterns = [
|
||||||
'cislo/<int:trocnik>.<str:tcislo>/odmeny/<int:frocnik>.<str:fcislo>/',
|
'cislo/<int:trocnik>.<str:tcislo>/odmeny/<int:frocnik>.<str:fcislo>/',
|
||||||
org_required(views.OdmenyView.as_view()),
|
org_required(views.OdmenyView.as_view()),
|
||||||
name="seminar_archiv_odmeny"),
|
name="seminar_archiv_odmeny"),
|
||||||
path(
|
|
||||||
'soustredeni/<int:soustredeni>/obalky.pdf',
|
|
||||||
org_required(views.soustredeniObalkyView),
|
|
||||||
name='seminar_soustredeni_obalky'
|
|
||||||
),
|
|
||||||
|
|
||||||
re_path(r'^temp/vue/.*$',views.VueTestView.as_view(),name='vue_test_view'),
|
re_path(r'^temp/vue/.*$',views.VueTestView.as_view(),name='vue_test_view'),
|
||||||
path('temp/image_upload/', views.NahrajObrazekKTreeNoduView.as_view()),
|
path('temp/image_upload/', views.NahrajObrazekKTreeNoduView.as_view()),
|
||||||
|
|
|
@ -14,7 +14,7 @@ from django.core.exceptions import PermissionDenied
|
||||||
|
|
||||||
import seminar.models as s
|
import seminar.models as s
|
||||||
import seminar.models as m
|
import seminar.models as m
|
||||||
from seminar.models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Tema, Clanek # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci
|
from seminar.models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Organizator, Resitel, Novinky, Tema, Clanek # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci
|
||||||
#from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
|
#from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
|
||||||
from seminar import utils, treelib
|
from seminar import utils, treelib
|
||||||
import seminar.forms as f
|
import seminar.forms as f
|
||||||
|
@ -34,7 +34,6 @@ import os
|
||||||
import os.path as op
|
import os.path as op
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import csv
|
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -850,53 +849,6 @@ def TitulyView(request, rocnik, cislo):
|
||||||
return render(request, 'seminar/archiv/tituly.tex',
|
return render(request, 'seminar/archiv/tituly.tex',
|
||||||
{'resitele': resitele,'jmenovci':jmenovci},content_type="text/plain")
|
{'resitele': resitele,'jmenovci':jmenovci},content_type="text/plain")
|
||||||
|
|
||||||
### Soustredeni
|
|
||||||
|
|
||||||
class SoustredeniListView(generic.ListView):
|
|
||||||
model = Soustredeni
|
|
||||||
template_name = 'seminar/soustredeni/seznam_soustredeni.html'
|
|
||||||
|
|
||||||
def soustredeniObalkyView(request,soustredeni):
|
|
||||||
soustredeni = get_object_or_404(Soustredeni,id = soustredeni)
|
|
||||||
return obalkyView(request,soustredeni.ucastnici.all())
|
|
||||||
|
|
||||||
|
|
||||||
class SoustredeniUcastniciBaseView(generic.ListView):
|
|
||||||
model = Soustredeni_Ucastnici
|
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
soustredeni = get_object_or_404(
|
|
||||||
Soustredeni,
|
|
||||||
pk=self.kwargs["soustredeni"]
|
|
||||||
)
|
|
||||||
return Soustredeni_Ucastnici.objects.filter(
|
|
||||||
soustredeni=soustredeni).select_related('resitel')
|
|
||||||
|
|
||||||
|
|
||||||
class SoustredeniMailyUcastnikuView(SoustredeniUcastniciBaseView):
|
|
||||||
""" Seznam e-mailů řešitelů oddělených čárkami. """
|
|
||||||
model = Soustredeni_Ucastnici
|
|
||||||
template_name = 'seminar/soustredeni/maily_ucastniku.txt'
|
|
||||||
|
|
||||||
|
|
||||||
class SoustredeniUcastniciView(SoustredeniUcastniciBaseView):
|
|
||||||
""" HTML tabulka účastníků pro tisk. """
|
|
||||||
model = Soustredeni_Ucastnici
|
|
||||||
template_name = 'seminar/soustredeni/seznam_ucastniku.html'
|
|
||||||
|
|
||||||
def soustredeniUcastniciExportView(request,soustredeni):
|
|
||||||
soustredeni = get_object_or_404(Soustredeni,id = soustredeni)
|
|
||||||
ucastnici = Resitel.objects.filter(soustredeni=soustredeni)
|
|
||||||
response = HttpResponse(content_type='text/csv')
|
|
||||||
response['Content-Disposition'] = 'attachment; filename="ucastnici.csv"'
|
|
||||||
|
|
||||||
writer = csv.writer(response)
|
|
||||||
writer.writerow(["jmeno", "prijmeni", "rok_maturity", "telefon", "email", "ulice", "mesto", "psc","stat"])
|
|
||||||
for u in ucastnici:
|
|
||||||
o = u.osoba
|
|
||||||
writer.writerow([o.jmeno, o.prijmeni, str(u.rok_maturity), o.telefon, o.email, o.ulice, o.mesto, o.psc, o.stat.name])
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
### Články
|
### Články
|
||||||
def group_by_rocnik(clanky):
|
def group_by_rocnik(clanky):
|
||||||
|
|
5
soustredeni/__init__.py
Normal file
5
soustredeni/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
"""
|
||||||
|
Obsahuje vše (až na přednášky) ohledně soustředění.
|
||||||
|
|
||||||
|
TODO stvrzenky?
|
||||||
|
"""
|
43
soustredeni/admin.py
Normal file
43
soustredeni/admin.py
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.forms import widgets
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
from seminar.models import soustredeni as m
|
||||||
|
|
||||||
|
|
||||||
|
class SoustredeniUcastniciInline(admin.TabularInline):
|
||||||
|
model = m.Soustredeni_Ucastnici
|
||||||
|
extra = 1
|
||||||
|
fields = ['resitel','poznamka']
|
||||||
|
autocomplete_fields = ['resitel']
|
||||||
|
ordering = ['resitel__osoba__jmeno', 'resitel__osoba__prijmeni']
|
||||||
|
formfield_overrides = {
|
||||||
|
models.TextField: {'widget': widgets.TextInput}
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_queryset(self,request):
|
||||||
|
qs = super().get_queryset(request)
|
||||||
|
return qs.select_related('resitel','soustredeni')
|
||||||
|
|
||||||
|
|
||||||
|
class SoustredeniOrganizatoriInline(admin.TabularInline):
|
||||||
|
model = m.Soustredeni.organizatori.through
|
||||||
|
extra = 1
|
||||||
|
fields = ['organizator','poznamka']
|
||||||
|
autocomplete_fields = ['organizator']
|
||||||
|
ordering = ['organizator__osoba__jmeno','organizator__prijmeni']
|
||||||
|
formfield_overrides = {
|
||||||
|
models.TextField: {'widget': widgets.TextInput}
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_queryset(self,request):
|
||||||
|
qs = super().get_queryset(request)
|
||||||
|
return qs.select_related('organizator', 'soustredeni')
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(m.Soustredeni)
|
||||||
|
class SoustredeniAdmin(admin.ModelAdmin):
|
||||||
|
model = m.Soustredeni
|
||||||
|
inline_type = 'tabular'
|
||||||
|
inlines = [SoustredeniUcastniciInline, SoustredeniOrganizatoriInline]
|
||||||
|
|
5
soustredeni/apps.py
Normal file
5
soustredeni/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class SoustredeniConfig(AppConfig):
|
||||||
|
name = 'soustredeni'
|
0
soustredeni/migrations/__init__.py
Normal file
0
soustredeni/migrations/__init__.py
Normal file
35
soustredeni/urls.py
Normal file
35
soustredeni/urls.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
from django.urls import path, include
|
||||||
|
from . import views
|
||||||
|
from seminar.utils import org_required
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path(
|
||||||
|
'soustredeni/probehlo/',
|
||||||
|
views.SoustredeniListView.as_view(),
|
||||||
|
name='seminar_seznam_soustredeni'
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'soustredeni/<int:soustredeni>/seznam_ucastniku',
|
||||||
|
org_required(views.SoustredeniUcastniciView.as_view()),
|
||||||
|
name='soustredeni_ucastnici'
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'soustredeni/<int:soustredeni>/maily_ucastniku',
|
||||||
|
org_required(views.SoustredeniMailyUcastnikuView.as_view()),
|
||||||
|
name='maily_ucastniku'
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'soustredeni/<int:soustredeni>/export_ucastniku',
|
||||||
|
org_required(views.soustredeniUcastniciExportView),
|
||||||
|
name='soustredeni_ucastnici_export'
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'soustredeni/<int:soustredeni>/obalky.pdf',
|
||||||
|
org_required(views.soustredeniObalkyView),
|
||||||
|
name='seminar_soustredeni_obalky'
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'soustredeni/<int:soustredeni>/fotogalerie/',
|
||||||
|
include('galerie.urls')
|
||||||
|
),
|
||||||
|
]
|
55
soustredeni/views.py
Normal file
55
soustredeni/views.py
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.views import generic
|
||||||
|
from seminar.models import Soustredeni, Resitel, Soustredeni_Ucastnici # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci
|
||||||
|
import csv
|
||||||
|
|
||||||
|
from seminar.views import obalkyView
|
||||||
|
|
||||||
|
|
||||||
|
class SoustredeniListView(generic.ListView):
|
||||||
|
model = Soustredeni
|
||||||
|
template_name = 'soustredeni/seznam_soustredeni.html'
|
||||||
|
|
||||||
|
|
||||||
|
def soustredeniObalkyView(request, soustredeni):
|
||||||
|
soustredeni = get_object_or_404(Soustredeni, id=soustredeni)
|
||||||
|
return obalkyView(request, soustredeni.ucastnici.all())
|
||||||
|
|
||||||
|
|
||||||
|
class SoustredeniUcastniciBaseView(generic.ListView):
|
||||||
|
model = Soustredeni_Ucastnici
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
soustredeni = get_object_or_404(
|
||||||
|
Soustredeni,
|
||||||
|
pk=self.kwargs["soustredeni"]
|
||||||
|
)
|
||||||
|
return Soustredeni_Ucastnici.objects.filter(
|
||||||
|
soustredeni=soustredeni).select_related('resitel')
|
||||||
|
|
||||||
|
|
||||||
|
class SoustredeniMailyUcastnikuView(SoustredeniUcastniciBaseView):
|
||||||
|
""" Seznam e-mailů řešitelů oddělených čárkami. """
|
||||||
|
model = Soustredeni_Ucastnici
|
||||||
|
template_name = 'soustredeni/maily_ucastniku.txt'
|
||||||
|
|
||||||
|
|
||||||
|
class SoustredeniUcastniciView(SoustredeniUcastniciBaseView):
|
||||||
|
""" HTML tabulka účastníků pro tisk. """
|
||||||
|
model = Soustredeni_Ucastnici
|
||||||
|
template_name = 'soustredeni/seznam_ucastniku.html'
|
||||||
|
|
||||||
|
|
||||||
|
def soustredeniUcastniciExportView(request, soustredeni):
|
||||||
|
soustredeni = get_object_or_404(Soustredeni, id=soustredeni)
|
||||||
|
ucastnici = Resitel.objects.filter(soustredeni=soustredeni)
|
||||||
|
response = HttpResponse(content_type='text/csv')
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="ucastnici.csv"'
|
||||||
|
|
||||||
|
writer = csv.writer(response)
|
||||||
|
writer.writerow(["jmeno", "prijmeni", "rok_maturity", "telefon", "email", "ulice", "mesto", "psc","stat"])
|
||||||
|
for u in ucastnici:
|
||||||
|
o = u.osoba
|
||||||
|
writer.writerow([o.jmeno, o.prijmeni, str(u.rok_maturity), o.telefon, o.email, o.ulice, o.mesto, o.psc, o.stat.name])
|
||||||
|
return response
|
Loading…
Reference in a new issue