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',
|
||||
'vysledkovky',
|
||||
'personalni',
|
||||
'soustredeni',
|
||||
|
||||
# Admin upravy:
|
||||
|
||||
|
|
|
@ -22,10 +22,13 @@ urlpatterns = [
|
|||
|
||||
# Korekturovaci aplikace (ma vlastni podadresare)
|
||||
path('', include('korektury.urls')),
|
||||
|
||||
|
||||
# Prednaskova aplikace (ma vlastni podadresare)
|
||||
path('', include('prednasky.urls')),
|
||||
|
||||
# Soustredkova aplikace (ma vlastni podadresare)
|
||||
path('', include('soustredeni.urls')),
|
||||
|
||||
# Personalni aplikace (ma vlastni podadresare)
|
||||
# (profil, osobní údaje, ..., ne autentizace, viz dále)
|
||||
path('', include('personalni.urls')),
|
||||
|
|
|
@ -150,41 +150,6 @@ class ResitelInline(admin.TabularInline):
|
|||
model = m.Resitel
|
||||
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.Obrazek)
|
||||
|
|
|
@ -2,3 +2,4 @@ from .models_all import *
|
|||
from .odevzdavatko import *
|
||||
from .base 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"})
|
||||
|
||||
|
||||
@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)
|
||||
# Pozor na následující řádek. *Nekrmit, asi kouše!*
|
||||
class Problem(SeminarModelBase,PolymorphicModel):
|
||||
|
@ -658,20 +596,6 @@ def aux_generate_filename(self, filename):
|
|||
clean)
|
||||
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):
|
||||
"""Kus pohádky před/za úlohou v čísle"""
|
||||
|
@ -718,124 +642,6 @@ class Pohadka(SeminarModelBase):
|
|||
# Neexistující *Node nemá smysl aktualizovat.
|
||||
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 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('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
|
||||
# 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'),
|
||||
|
@ -101,11 +75,6 @@ urlpatterns = [
|
|||
'cislo/<int:trocnik>.<str:tcislo>/odmeny/<int:frocnik>.<str:fcislo>/',
|
||||
org_required(views.OdmenyView.as_view()),
|
||||
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'),
|
||||
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 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 seminar import utils, treelib
|
||||
import seminar.forms as f
|
||||
|
@ -34,7 +34,6 @@ import os
|
|||
import os.path as op
|
||||
from django.conf import settings
|
||||
import unicodedata
|
||||
import csv
|
||||
import logging
|
||||
import time
|
||||
|
||||
|
@ -850,53 +849,6 @@ def TitulyView(request, rocnik, cislo):
|
|||
return render(request, 'seminar/archiv/tituly.tex',
|
||||
{'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
|
||||
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