Merge branch 'master' into reforma_pohlavi
This commit is contained in:
commit
37f988f478
73 changed files with 1653 additions and 140 deletions
|
@ -1,9 +1,10 @@
|
|||
from django.test import TestCase
|
||||
from django.test import TestCase, tag
|
||||
from django.urls import reverse
|
||||
import seminar.models as m
|
||||
import seminar.views as v
|
||||
from seminar.utils import sync_skoly
|
||||
|
||||
@tag('stejny-model-na-produkci')
|
||||
class OrgSkolyAutocompleteTestCase(TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
|
|
@ -271,62 +271,62 @@
|
|||
},
|
||||
{
|
||||
"codename": "add_konfera",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "konfera"
|
||||
},
|
||||
{
|
||||
"codename": "change_konfera",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "konfera"
|
||||
},
|
||||
{
|
||||
"codename": "delete_konfera",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "konfera"
|
||||
},
|
||||
{
|
||||
"codename": "view_konfera",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "konfera"
|
||||
},
|
||||
{
|
||||
"codename": "add_konfery_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "konfery_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "change_konfery_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "konfery_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "delete_konfery_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "konfery_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "view_konfery_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "konfery_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "add_nastaveni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "various",
|
||||
"ct_model": "nastaveni"
|
||||
},
|
||||
{
|
||||
"codename": "change_nastaveni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "various",
|
||||
"ct_model": "nastaveni"
|
||||
},
|
||||
{
|
||||
"codename": "delete_nastaveni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "various",
|
||||
"ct_model": "nastaveni"
|
||||
},
|
||||
{
|
||||
"codename": "view_nastaveni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "various",
|
||||
"ct_model": "nastaveni"
|
||||
},
|
||||
{
|
||||
|
@ -351,22 +351,22 @@
|
|||
},
|
||||
{
|
||||
"codename": "change_organizator",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "organizator"
|
||||
},
|
||||
{
|
||||
"codename": "view_organizator",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "organizator"
|
||||
},
|
||||
{
|
||||
"codename": "change_osoba",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "osoba"
|
||||
},
|
||||
{
|
||||
"codename": "view_osoba",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "osoba"
|
||||
},
|
||||
{
|
||||
|
@ -391,22 +391,22 @@
|
|||
},
|
||||
{
|
||||
"codename": "add_prijemce",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "prijemce"
|
||||
},
|
||||
{
|
||||
"codename": "change_prijemce",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "prijemce"
|
||||
},
|
||||
{
|
||||
"codename": "delete_prijemce",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "prijemce"
|
||||
},
|
||||
{
|
||||
"codename": "view_prijemce",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "prijemce"
|
||||
},
|
||||
{
|
||||
|
@ -431,12 +431,12 @@
|
|||
},
|
||||
{
|
||||
"codename": "change_resitel",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "resitel"
|
||||
},
|
||||
{
|
||||
"codename": "view_resitel",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "resitel"
|
||||
},
|
||||
{
|
||||
|
@ -461,82 +461,82 @@
|
|||
},
|
||||
{
|
||||
"codename": "add_skola",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "skola"
|
||||
},
|
||||
{
|
||||
"codename": "change_skola",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "skola"
|
||||
},
|
||||
{
|
||||
"codename": "delete_skola",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "skola"
|
||||
},
|
||||
{
|
||||
"codename": "view_skola",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "personalni",
|
||||
"ct_model": "skola"
|
||||
},
|
||||
{
|
||||
"codename": "add_soustredeni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni"
|
||||
},
|
||||
{
|
||||
"codename": "change_soustredeni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni"
|
||||
},
|
||||
{
|
||||
"codename": "delete_soustredeni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni"
|
||||
},
|
||||
{
|
||||
"codename": "view_soustredeni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni"
|
||||
},
|
||||
{
|
||||
"codename": "add_soustredeni_organizatori",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni_organizatori"
|
||||
},
|
||||
{
|
||||
"codename": "change_soustredeni_organizatori",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni_organizatori"
|
||||
},
|
||||
{
|
||||
"codename": "delete_soustredeni_organizatori",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni_organizatori"
|
||||
},
|
||||
{
|
||||
"codename": "view_soustredeni_organizatori",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni_organizatori"
|
||||
},
|
||||
{
|
||||
"codename": "add_soustredeni_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "change_soustredeni_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "delete_soustredeni_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "view_soustredeni_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_app_label": "soustredeni",
|
||||
"ct_model": "soustredeni_ucastnici"
|
||||
},
|
||||
{
|
||||
|
@ -619,4 +619,4 @@
|
|||
"ct_app_label": "taggit",
|
||||
"ct_model": "taggeditem"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
13
galerie/migrations/0011_pre_split_soustredeni.py
Normal file
13
galerie/migrations/0011_pre_split_soustredeni.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Generated by Django 4.2.11 on 2024-04-30 21:53
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('galerie', '0010_auto_20200819_0947'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
20
galerie/migrations/0012_soustredeni_relink.py
Normal file
20
galerie/migrations/0012_soustredeni_relink.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Generated by Django 4.2.11 on 2024-05-01 13:07
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('soustredeni', '0001_split_from_seminar'),
|
||||
('galerie', '0011_pre_split_soustredeni'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='soustredeni',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='soustredeni.soustredeni'),
|
||||
),
|
||||
]
|
14
galerie/migrations/0013_post_split_soustredeni.py
Normal file
14
galerie/migrations/0013_post_split_soustredeni.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Generated by Django 4.2.11 on 2024-05-01 13:35
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('galerie', '0012_soustredeni_relink'),
|
||||
('soustredeni', '0003_post_split_soustredeni'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
|
@ -7,7 +7,7 @@ from imagekit.processors import ResizeToFit, Transpose
|
|||
|
||||
import os
|
||||
|
||||
from seminar.models import Soustredeni
|
||||
from soustredeni.models import Soustredeni
|
||||
|
||||
VZDY=0
|
||||
ORG=1
|
||||
|
|
13
korektury/migrations/0021_auto_20240312_2124.py
Normal file
13
korektury/migrations/0021_auto_20240312_2124.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Generated by Django 4.2.8 on 2024-03-12 20:24
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('korektury', '0020_lepsi_popis_nazvu_PDF_v_adminu'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
|
@ -0,0 +1,30 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-19 21:35
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('personalni', '0003_initial'),
|
||||
('korektury', '0021_auto_20240312_2124'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='komentar',
|
||||
name='autor',
|
||||
field=models.ForeignKey(blank=True, help_text='Autor komentáře', null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.organizator'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='korekturovanepdf',
|
||||
name='org',
|
||||
field=models.ForeignKey(blank=True, default=None, help_text='Zodpovědný organizátor za obsah', null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.organizator'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='oprava',
|
||||
name='autor',
|
||||
field=models.ForeignKey(blank=True, help_text='Autor opravy', null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.organizator'),
|
||||
),
|
||||
]
|
14
korektury/migrations/0023_personalni_post_migrate.py
Normal file
14
korektury/migrations/0023_personalni_post_migrate.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-26 21:25
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('korektury', '0022_alter_komentar_autor_alter_korekturovanepdf_org_and_more'),
|
||||
('personalni', '0005_personalni_post_migrate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
|
@ -20,7 +20,7 @@ from django.core.exceptions import ObjectDoesNotExist
|
|||
from django.utils.functional import cached_property
|
||||
from django.utils.text import get_valid_filename
|
||||
|
||||
from seminar.models import Organizator
|
||||
from personalni.models import Organizator
|
||||
|
||||
import subprocess
|
||||
from reversion import revisions as reversion
|
||||
|
|
13
personalni/migrations/0002_auto_20240312_2118.py
Normal file
13
personalni/migrations/0002_auto_20240312_2118.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Generated by Django 4.2.8 on 2024-03-12 20:18
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('personalni', '0001_skupiny'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
146
personalni/migrations/0003_initial.py
Normal file
146
personalni/migrations/0003_initial.py
Normal file
|
@ -0,0 +1,146 @@
|
|||
# Generated by Django 4.2.8 on 2024-03-12 21:10
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
import django_countries.fields
|
||||
import imagekit.models.fields
|
||||
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
def nastav_nove_contenttypes(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
for m in ('resitel', 'organizator', 'osoba', 'skola', 'prijemce'):
|
||||
oct = ContentType.objects.filter(app_label='seminar', model=m)
|
||||
oct.update(app_label='personalni')
|
||||
|
||||
def nastav_stare_contenttypes(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
for m in ('resitel', 'organizator', 'osoba', 'skola', 'prijemce'):
|
||||
nct = ContentType.objects.filter(app_label='personalni', model=m)
|
||||
nct.update(app_label='seminar')
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('personalni', '0002_auto_20240312_2118'),
|
||||
('seminar', '0118_alter_organizator_options_alter_osoba_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(nastav_nove_contenttypes, nastav_stare_contenttypes),
|
||||
migrations.CreateModel(
|
||||
name='Organizator',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('vytvoreno', models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='Vytvořeno')),
|
||||
('organizuje_od', models.DateTimeField(blank=True, null=True, verbose_name='Organizuje od')),
|
||||
('organizuje_do', models.DateTimeField(blank=True, null=True, verbose_name='Organizuje do')),
|
||||
('studuje', models.CharField(blank=True, help_text="Např. 'Studuje Obecnou fyziku (Bc.), 3. ročník', 'Vystudovala Diskrétní modely a algoritmy (Mgr.)' nebo 'Přednáší na MFF'", max_length=256, null=True, verbose_name='Studium aj.')),
|
||||
('strucny_popis_organizatora', models.TextField(blank=True, null=True, verbose_name='Stručný popis organizátora')),
|
||||
('skola', models.CharField(blank=True, help_text='Škola, např. MFF, VŠCHT, VUT, ... prostě aby se nemuselo psát do studuješkolu, ale jen obor, možnost zobrazit zvlášť', max_length=256, null=True, verbose_name='Škola, kterou studuje')),
|
||||
('osoba', models.OneToOneField(help_text='osobní údaje organizátora', on_delete=django.db.models.deletion.PROTECT, related_name='org', to='personalni.osoba', verbose_name='osoba')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Organizátor',
|
||||
'verbose_name_plural': 'Organizátoři',
|
||||
'db_table': 'seminar_organizator',
|
||||
'ordering': ['-organizuje_do', 'osoba__jmeno', 'osoba__prijmeni'],
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Osoba',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('jmeno', models.CharField(max_length=256, verbose_name='jméno')),
|
||||
('prijmeni', models.CharField(max_length=256, verbose_name='příjmení')),
|
||||
('prezdivka', models.CharField(blank=True, max_length=256, null=True, verbose_name='přezdívka')),
|
||||
('pohlavi_muz', models.BooleanField(default=False, verbose_name='pohlaví (muž)')),
|
||||
('email', models.EmailField(blank=True, default='', max_length=256, verbose_name='e-mail')),
|
||||
('telefon', models.CharField(blank=True, default='', max_length=256, verbose_name='telefon')),
|
||||
('datum_narozeni', models.DateField(blank=True, null=True, verbose_name='datum narození')),
|
||||
('datum_souhlasu_udaje', models.DateField(blank=True, help_text='Datum souhlasu se zpracováním osobních údajů', null=True, verbose_name='datum souhlasu (údaje)')),
|
||||
('datum_souhlasu_zasilani', models.DateField(blank=True, help_text='Datum souhlasu se zasíláním MFF materiálů', null=True, verbose_name='datum souhlasu (spam)')),
|
||||
('datum_registrace', models.DateField(default=django.utils.timezone.now, verbose_name='datum registrace do semináře')),
|
||||
('ulice', models.CharField(blank=True, default='', max_length=256, verbose_name='ulice')),
|
||||
('mesto', models.CharField(blank=True, default='', max_length=256, verbose_name='město')),
|
||||
('psc', models.CharField(blank=True, default='', max_length=32, verbose_name='PSČ')),
|
||||
('stat', django_countries.fields.CountryField(default='CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát')),
|
||||
('jak_se_dozvedeli', models.TextField(blank=True, verbose_name='Jak se dozvěděli')),
|
||||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k osobě (plain text)', verbose_name='neveřejná poznámka')),
|
||||
('foto', imagekit.models.fields.ProcessedImageField(blank=True, help_text='Vlož fotografii osoby o libovolné velikosti', null=True, upload_to='image_osoby/velke/%Y/', verbose_name='Fotografie osoby')),
|
||||
('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL, verbose_name='uživatel')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Osoba',
|
||||
'verbose_name_plural': 'Osoby',
|
||||
'db_table': 'seminar_osoby',
|
||||
'ordering': ['prijmeni', 'jmeno'],
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Prijemce',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k příemci čísel (plain text)', verbose_name='neveřejná poznámka')),
|
||||
('zasilat_cislo_emailem', models.BooleanField(default=False, help_text='True pokud chce příjemce dostávat číslo emailem', verbose_name='zasílat číslo emailem')),
|
||||
('osoba', models.OneToOneField(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='personalni.osoba', verbose_name='komu')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'příjemce',
|
||||
'verbose_name_plural': 'příjemce',
|
||||
'db_table': 'seminar_prijemce',
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Resitel',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('prezdivka_resitele', models.CharField(blank=True, max_length=256, null=True, unique=True, verbose_name='přezdívka řešitele')),
|
||||
('rok_maturity', models.IntegerField(blank=True, null=True, verbose_name='rok maturity')),
|
||||
('zasilat', models.CharField(choices=[('domu', 'Domů'), ('do_skoly', 'Do školy'), ('nikam', 'Nezasílat papírově')], default='domu', max_length=32, verbose_name='kam zasílat')),
|
||||
('zasilat_cislo_emailem', models.BooleanField(default=False, help_text='True pokud chce řešitel dostávat číslo emailem', verbose_name='zasílat číslo emailem')),
|
||||
('zasilat_cislo_papirove', models.BooleanField(default=True, help_text='True pokud chce řešitel dostávat číslo papírově', verbose_name='zasílat číslo papírově')),
|
||||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k řešiteli (plain text)', verbose_name='neveřejná poznámka')),
|
||||
('osoba', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='personalni.osoba', verbose_name='osoba')),
|
||||
('skola', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.skola', verbose_name='škola')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Řešitel',
|
||||
'verbose_name_plural': 'Řešitelé',
|
||||
'db_table': 'seminar_resitele',
|
||||
'ordering': ['osoba'],
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Skola',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('aesop_id', models.CharField(blank=True, default='', help_text='Aesopi ID typu "izo:..." nebo "aesop:..."', max_length=32, verbose_name='Aesop ID')),
|
||||
('izo', models.CharField(blank=True, help_text='IZO školy (jen české školy)', max_length=32, verbose_name='IZO')),
|
||||
('nazev', models.CharField(help_text='Celý název školy', max_length=256, verbose_name='název')),
|
||||
('kratky_nazev', models.CharField(blank=True, help_text='Zkrácený název pro zobrazení ve výsledkovce', max_length=256, verbose_name='zkrácený název')),
|
||||
('ulice', models.CharField(max_length=256, verbose_name='ulice')),
|
||||
('mesto', models.CharField(max_length=256, verbose_name='město')),
|
||||
('psc', models.CharField(max_length=32, verbose_name='PSČ')),
|
||||
('stat', django_countries.fields.CountryField(default='CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát')),
|
||||
('je_zs', models.BooleanField(default=True, verbose_name='základní stupeň')),
|
||||
('je_ss', models.BooleanField(default=True, verbose_name='střední stupeň')),
|
||||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka ke škole (plain text)', verbose_name='neveřejná poznámka')),
|
||||
('kontaktni_osoba', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.osoba', verbose_name='Kontaktní osoba')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Škola',
|
||||
'verbose_name_plural': 'Školy',
|
||||
'db_table': 'seminar_skoly',
|
||||
'ordering': ['mesto', 'nazev'],
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
]
|
|
@ -0,0 +1,34 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-26 21:11
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('personalni', '0003_initial'),
|
||||
('seminar', '0120_remove_osoba_user_remove_prijemce_osoba_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='organizator',
|
||||
options={'ordering': ['-organizuje_do', 'osoba__jmeno', 'osoba__prijmeni'], 'verbose_name': 'Organizátor', 'verbose_name_plural': 'Organizátoři'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='osoba',
|
||||
options={'ordering': ['prijmeni', 'jmeno'], 'verbose_name': 'Osoba', 'verbose_name_plural': 'Osoby'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='prijemce',
|
||||
options={'verbose_name': 'příjemce', 'verbose_name_plural': 'příjemce'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='resitel',
|
||||
options={'ordering': ['osoba'], 'verbose_name': 'Řešitel', 'verbose_name_plural': 'Řešitelé'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='skola',
|
||||
options={'ordering': ['mesto', 'nazev'], 'verbose_name': 'Škola', 'verbose_name_plural': 'Školy'},
|
||||
),
|
||||
]
|
13
personalni/migrations/0005_personalni_post_migrate.py
Normal file
13
personalni/migrations/0005_personalni_post_migrate.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-26 21:25
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('personalni', '0004_alter_organizator_options_alter_osoba_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
13
personalni/migrations/0006_pre_split_soustredeni.py
Normal file
13
personalni/migrations/0006_pre_split_soustredeni.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Generated by Django 4.2.11 on 2024-04-30 21:53
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('personalni', '0005_personalni_post_migrate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
|
@ -12,7 +12,7 @@ from django_countries.fields import CountryField
|
|||
|
||||
from reversion import revisions as reversion
|
||||
|
||||
from .base import SeminarModelBase
|
||||
from seminar.models.base import SeminarModelBase
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -297,7 +297,7 @@ class Resitel(SeminarModelBase):
|
|||
def vsechny_body(self):
|
||||
"Spočítá body odjakživa."
|
||||
vsechna_reseni = self.reseni_set.all()
|
||||
from .odevzdavatko import Hodnoceni
|
||||
from seminar.models.odevzdavatko import Hodnoceni
|
||||
vsechna_hodnoceni = Hodnoceni.objects.filter(
|
||||
reseni__in=vsechna_reseni)
|
||||
return sum(h.body for h in list(vsechna_hodnoceni) if h.body is not None)
|
||||
|
@ -344,7 +344,7 @@ class Resitel(SeminarModelBase):
|
|||
# - body z 25. ročníku a dříve byly shledány dvakrát hodnotnějšími
|
||||
# - proto se započítávají dvojnásobně a byly posunuté hranice titulů
|
||||
# - staré tituly se ale nemají odebrat, pokud řešitel v t.č. minulém (26.) ročníku měl titul, má ho mít pořád.
|
||||
from .odevzdavatko import Hodnoceni
|
||||
from seminar.models.odevzdavatko import Hodnoceni
|
||||
hodnoceni_do_25_rocniku = Hodnoceni.objects.filter(deadline_body__cislo__rocnik__rocnik__lte=25,reseni__in=self.reseni_set.all())
|
||||
novejsi_hodnoceni = Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()).difference(hodnoceni_do_25_rocniku)
|
||||
|
||||
|
@ -382,7 +382,7 @@ class Resitel(SeminarModelBase):
|
|||
else:
|
||||
return Titul.akad
|
||||
|
||||
from .odevzdavatko import Hodnoceni
|
||||
from seminar.models.odevzdavatko import Hodnoceni
|
||||
hodnoceni_do_26_rocniku = Hodnoceni.objects.filter(deadline_body__cislo__rocnik__rocnik__lte=26,reseni__in=self.reseni_set.all())
|
||||
novejsi_body = body_z_hodnoceni(
|
||||
Hodnoceni.objects.filter(reseni__in=self.reseni_set.all())
|
||||
|
@ -411,6 +411,17 @@ class Resitel(SeminarModelBase):
|
|||
|
||||
@reversion.register(ignore_duplicates=True)
|
||||
class Organizator(SeminarModelBase):
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Organizátor'
|
||||
verbose_name_plural = 'Organizátoři'
|
||||
# Řadí aktivní orgy na začátek, pod tím v pořadí od nejstarších neaktivní orgy.
|
||||
# TODO: Chtěl bych spíš mít nejstarší orgy dole.
|
||||
# TODO: Zohledňovat přezdívky?
|
||||
# TODO: Sjednotit s tím, jak se řadí organizátoři v seznau orgů na webu
|
||||
db_table = 'seminar_organizator'
|
||||
ordering = ['-organizuje_do', 'osoba__jmeno', 'osoba__prijmeni']
|
||||
|
||||
osoba = models.OneToOneField(Osoba, verbose_name='osoba', related_name='org',
|
||||
help_text='osobní údaje organizátora', null=False, blank=False,
|
||||
on_delete=models.PROTECT)
|
||||
|
@ -452,12 +463,3 @@ class Organizator(SeminarModelBase):
|
|||
self.osoba.prijmeni)
|
||||
else:
|
||||
return "{} {}".format(self.osoba.jmeno, self.osoba.prijmeni)
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Organizátor'
|
||||
verbose_name_plural = 'Organizátoři'
|
||||
# Řadí aktivní orgy na začátek, pod tím v pořadí od nejstarších neaktivní orgy.
|
||||
# TODO: Chtěl bych spíš mít nejstarší orgy dole.
|
||||
# TODO: Zohledňovat přezdívky?
|
||||
# TODO: Sjednotit s tím, jak se řadí organizátoři v seznau orgů na webu
|
||||
ordering = ['-organizuje_do', 'osoba__jmeno', 'osoba__prijmeni']
|
|
@ -13,18 +13,18 @@
|
|||
<li>soustředění</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/admin/seminar/novinky/add/"><strong>přidat novinku</strong></a> na web</li>
|
||||
<li><a href="{% url 'admin:seminar_novinky_add' %}"><strong>přidat novinku</strong></a> na web</li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
<h2><strong>Tvorba čísla</strong></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="/admin/seminar/problem/add/"><strong>přidat téma</strong></a></li>
|
||||
<li><a href="{% url 'admin:seminar_problem_add' %}"><strong>přidat téma</strong></a></li>
|
||||
<li><strong>korektury</strong>
|
||||
<ul>
|
||||
<li><a href="/korektury/">korekturování</a></li>
|
||||
<li><a href="/admin/korektury/korekturovanepdf/add/">přidat pdf k opravám</a></li>
|
||||
<li><a href="{% url 'korektury_list' %}">korekturování</a></li>
|
||||
<li><a href="{% url 'admin:korektury_korekturovanepdf_add' %}">přidat pdf k opravám</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
|
@ -70,15 +70,15 @@
|
|||
<h2><strong>Soustředění</strong></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="/admin/seminar/soustredeni/add/">přidat soustředění</a></li>
|
||||
<li><a href="{% url 'admin:soustredeni_soustredeni_add' %}">přidat soustředění</a></li>
|
||||
<li><strong>přednášky</strong>
|
||||
|
||||
<ul>
|
||||
<li><a href="/admin/prednasky/prednaska/">vypisování přednášek</a></li>
|
||||
<li><a href="{% url 'admin:prednasky_prednaska_add' %}">vypisování přednášek</a></li>
|
||||
<li>hlasování o přednáškách</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/soustredeni/probehlo/">proběhlá soustředění</a>
|
||||
<li><a href="{% url 'seminar_seznam_soustredeni' %}">proběhlá soustředění</a>
|
||||
<ul>
|
||||
<li>vytvoření galerie</li>
|
||||
<li>stažení seznamu účastníků</li>
|
||||
|
@ -91,7 +91,7 @@
|
|||
<h2><strong>Můj profil</strong></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="/admin/seminar/organizator/{{ organizator.id }}/change/"><strong>upravit </strong></a></li>
|
||||
<li><a href="{% url 'admin:personalni_organizator_change' organizator.id %}"><strong>upravit </strong></a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
@ -108,6 +108,6 @@
|
|||
</ul>
|
||||
|
||||
<hr />
|
||||
<p>Nemůžeš najít, co hledáš? Může to být v <a href="/admin/">administračním rozhraní webu</a>.</p>
|
||||
<p>Nemůžeš najít, co hledáš? Může to být v <a href="{% url 'admin:index' %}">administračním rozhraní webu</a>.</p>
|
||||
{% endblock content %}
|
||||
|
||||
|
|
13
prednasky/migrations/0013_auto_20240312_2124.py
Normal file
13
prednasky/migrations/0013_auto_20240312_2124.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Generated by Django 4.2.8 on 2024-03-12 20:24
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('prednasky', '0012_auto_20190610_2358'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
20
prednasky/migrations/0014_alter_prednaska_org.py
Normal file
20
prednasky/migrations/0014_alter_prednaska_org.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-19 21:35
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('personalni', '0003_initial'),
|
||||
('prednasky', '0013_auto_20240312_2124'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='prednaska',
|
||||
name='org',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='personalni.organizator'),
|
||||
),
|
||||
]
|
14
prednasky/migrations/0015_personalni_post_migrate.py
Normal file
14
prednasky/migrations/0015_personalni_post_migrate.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-26 21:25
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('prednasky', '0014_alter_prednaska_org'),
|
||||
('personalni', '0005_personalni_post_migrate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
13
prednasky/migrations/0016_pre_split_soustredeni.py
Normal file
13
prednasky/migrations/0016_pre_split_soustredeni.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Generated by Django 4.2.11 on 2024-04-30 21:53
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('prednasky', '0015_personalni_post_migrate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
20
prednasky/migrations/0017_soustredeni_relink.py
Normal file
20
prednasky/migrations/0017_soustredeni_relink.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Generated by Django 4.2.11 on 2024-05-01 13:07
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('soustredeni', '0001_split_from_seminar'),
|
||||
('prednasky', '0016_pre_split_soustredeni'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='seznam',
|
||||
name='soustredeni',
|
||||
field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='soustredeni.soustredeni'),
|
||||
),
|
||||
]
|
14
prednasky/migrations/0018_post_split_soustredeni.py
Normal file
14
prednasky/migrations/0018_post_split_soustredeni.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Generated by Django 4.2.11 on 2024-05-01 13:35
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('prednasky', '0017_soustredeni_relink'),
|
||||
('soustredeni', '0003_post_split_soustredeni'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
from django.db import models
|
||||
|
||||
from seminar.models import Organizator, Soustredeni
|
||||
from soustredeni.models import Soustredeni
|
||||
from personalni.models import Organizator
|
||||
|
||||
STAV_NAVRH = 1
|
||||
STAV_BUDE = 2
|
||||
|
|
17
seminar/migrations/0115_alter_nastaveni_options.py
Normal file
17
seminar/migrations/0115_alter_nastaveni_options.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 3.2.23 on 2023-12-11 19:14
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0114_related_name_se_zmenilo_a_django_chce_migraci_tak_dostane_migraci'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='nastaveni',
|
||||
options={'managed': False, 'verbose_name': 'Nastavení semináře'},
|
||||
),
|
||||
]
|
17
seminar/migrations/0116_delete_nastaveni.py
Normal file
17
seminar/migrations/0116_delete_nastaveni.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 3.2.23 on 2023-12-11 19:25
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0115_alter_nastaveni_options'),
|
||||
('various', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='Nastaveni',
|
||||
),
|
||||
]
|
16
seminar/migrations/0117_auto_20240312_2125.py
Normal file
16
seminar/migrations/0117_auto_20240312_2125.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Generated by Django 4.2.8 on 2024-03-12 20:25
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0116_delete_nastaveni'),
|
||||
('personalni', '0001_skupiny'),
|
||||
('korektury', '0021_auto_20240312_2124'),
|
||||
('sifrovacka', '0004_auto_20240312_2124'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 4.2.8 on 2024-03-12 20:44
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0117_auto_20240312_2125'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='organizator',
|
||||
options={'managed': False, 'ordering': ['-organizuje_do', 'osoba__jmeno', 'osoba__prijmeni'], 'verbose_name': 'Organizátor', 'verbose_name_plural': 'Organizátoři'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='osoba',
|
||||
options={'managed': False, 'ordering': ['prijmeni', 'jmeno'], 'verbose_name': 'Osoba', 'verbose_name_plural': 'Osoby'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='prijemce',
|
||||
options={'managed': False, 'verbose_name': 'příjemce', 'verbose_name_plural': 'příjemce'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='resitel',
|
||||
options={'managed': False, 'ordering': ['osoba'], 'verbose_name': 'Řešitel', 'verbose_name_plural': 'Řešitelé'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='skola',
|
||||
options={'managed': False, 'ordering': ['mesto', 'nazev'], 'verbose_name': 'Škola', 'verbose_name_plural': 'Školy'},
|
||||
),
|
||||
]
|
85
seminar/migrations/0119_alter_konfera_ucastnici_and_more.py
Normal file
85
seminar/migrations/0119_alter_konfera_ucastnici_and_more.py
Normal file
|
@ -0,0 +1,85 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-19 21:35
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('personalni', '0003_initial'),
|
||||
('seminar', '0118_alter_organizator_options_alter_osoba_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='konfera',
|
||||
name='ucastnici',
|
||||
field=models.ManyToManyField(help_text='Seznam účastníků konfery', through='seminar.Konfery_Ucastnici', to='personalni.resitel', verbose_name='účastníci konfery'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='konfery_ucastnici',
|
||||
name='resitel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='personalni.resitel', verbose_name='řešitel'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='novinky',
|
||||
name='autor',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.organizator', verbose_name='Autor novinky'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='orgtextnode',
|
||||
name='organizator',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='personalni.organizator', verbose_name='Organizátor'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='pohadka',
|
||||
name='autor',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.organizator', verbose_name='Autor pohádky'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problem',
|
||||
name='autor',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='autor_problemu_%(class)s', to='personalni.organizator', verbose_name='autor problému'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problem',
|
||||
name='garant',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='garant_problemu_%(class)s', to='personalni.organizator', verbose_name='garant zadaného problému'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problem',
|
||||
name='opravovatele',
|
||||
field=models.ManyToManyField(blank=True, related_name='opravovatele_%(class)s', to='personalni.organizator', verbose_name='opravovatelé'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='reseni',
|
||||
name='resitele',
|
||||
field=models.ManyToManyField(help_text='Seznam autorů řešení', through='seminar.Reseni_Resitele', to='personalni.resitel', verbose_name='autoři řešení'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='reseni_resitele',
|
||||
name='resitele',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='personalni.resitel', verbose_name='řešitel'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='soustredeni',
|
||||
name='organizatori',
|
||||
field=models.ManyToManyField(help_text='Seznam organizátorů soustředění', through='seminar.Soustredeni_Organizatori', to='personalni.organizator', verbose_name='Organizátoři soustředění'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='soustredeni',
|
||||
name='ucastnici',
|
||||
field=models.ManyToManyField(help_text='Seznam účastníků soustředění', through='seminar.Soustredeni_Ucastnici', to='personalni.resitel', verbose_name='účastníci soustředění'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='soustredeni_organizatori',
|
||||
name='organizator',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='personalni.organizator', verbose_name='organizátor'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='soustredeni_ucastnici',
|
||||
name='resitel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='personalni.resitel', verbose_name='řešitel'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,52 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-19 21:57
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0119_alter_konfera_ucastnici_and_more'),
|
||||
('personalni', '0003_initial'),
|
||||
('korektury', '0022_alter_komentar_autor_alter_korekturovanepdf_org_and_more'),
|
||||
('prednasky', '0014_alter_prednaska_org'),
|
||||
('sifrovacka', '0005_alter_odpoveducastnika_resitel'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='osoba',
|
||||
name='user',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='prijemce',
|
||||
name='osoba',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='resitel',
|
||||
name='osoba',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='resitel',
|
||||
name='skola',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='skola',
|
||||
name='kontaktni_osoba',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Organizator',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Osoba',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Prijemce',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Resitel',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Skola',
|
||||
),
|
||||
]
|
14
seminar/migrations/0121_personalni_post_migrate.py
Normal file
14
seminar/migrations/0121_personalni_post_migrate.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-26 21:25
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0120_remove_osoba_user_remove_prijemce_osoba_and_more'),
|
||||
('personalni', '0005_personalni_post_migrate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
16
seminar/migrations/0122_pre_split_soustredeni.py
Normal file
16
seminar/migrations/0122_pre_split_soustredeni.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Generated by Django 4.2.11 on 2024-04-30 21:54
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0121_personalni_post_migrate'),
|
||||
('personalni', '0006_pre_split_soustredeni'),
|
||||
('galerie', '0011_pre_split_soustredeni'),
|
||||
('prednasky', '0016_pre_split_soustredeni'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
33
seminar/migrations/0123_soustredeni_unmanage.py
Normal file
33
seminar/migrations/0123_soustredeni_unmanage.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 4.2.11 on 2024-04-30 22:17
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0122_pre_split_soustredeni'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='konfera',
|
||||
options={'managed': False, 'verbose_name': 'Konfera', 'verbose_name_plural': 'Konfery'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='konfery_ucastnici',
|
||||
options={'managed': False, 'ordering': ['konfera', 'resitel'], 'verbose_name': 'Účast na konfeře', 'verbose_name_plural': 'Účasti na konfeře'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='soustredeni',
|
||||
options={'managed': False, 'ordering': ['-rocnik__rocnik', '-datum_zacatku'], 'verbose_name': 'Soustředění', 'verbose_name_plural': 'Soustředění'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='soustredeni_organizatori',
|
||||
options={'managed': False, 'ordering': ['soustredeni', 'organizator'], 'verbose_name': 'Účast organizátorů na soustředění', 'verbose_name_plural': 'Účasti organizátorů na soustředění'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='soustredeni_ucastnici',
|
||||
options={'managed': False, 'ordering': ['soustredeni', 'resitel'], 'verbose_name': 'Účast na soustředění', 'verbose_name_plural': 'Účasti na soustředění'},
|
||||
),
|
||||
]
|
67
seminar/migrations/0124_remove_sous_from_seminar.py
Normal file
67
seminar/migrations/0124_remove_sous_from_seminar.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
# Generated by Django 4.2.11 on 2024-05-01 13:13
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0123_soustredeni_unmanage'),
|
||||
('soustredeni', '0001_split_from_seminar'),
|
||||
('galerie', '0012_soustredeni_relink'),
|
||||
('prednasky', '0017_soustredeni_relink'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='konfery_ucastnici',
|
||||
name='konfera',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='konfery_ucastnici',
|
||||
name='resitel',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='soustredeni',
|
||||
name='organizatori',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='soustredeni',
|
||||
name='rocnik',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='soustredeni',
|
||||
name='ucastnici',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='soustredeni_organizatori',
|
||||
name='organizator',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='soustredeni_organizatori',
|
||||
name='soustredeni',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='soustredeni_ucastnici',
|
||||
name='resitel',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='soustredeni_ucastnici',
|
||||
name='soustredeni',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Konfera',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Konfery_Ucastnici',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Soustredeni',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Soustredeni_Organizatori',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Soustredeni_Ucastnici',
|
||||
),
|
||||
]
|
14
seminar/migrations/0125_post_split_soustredeni.py
Normal file
14
seminar/migrations/0125_post_split_soustredeni.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Generated by Django 4.2.11 on 2024-05-01 13:35
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0124_remove_sous_from_seminar'),
|
||||
('soustredeni', '0003_post_split_soustredeni'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
|
@ -1,8 +1,13 @@
|
|||
from .tvorba import *
|
||||
from .odevzdavatko import *
|
||||
from .base import *
|
||||
from .personalni import *
|
||||
from .soustredeni import *
|
||||
from .pomocne import *
|
||||
from .treenode import *
|
||||
from .novinky import *
|
||||
|
||||
from various.models import Nastaveni
|
||||
from personalni.models import Organizator, Resitel, Skola, Prijemce, Osoba
|
||||
from soustredeni.models import Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Konfera, Konfery_Ucastnici
|
||||
|
||||
# Kvůli migr. 0041
|
||||
from soustredeni.models import generate_filename_konfera
|
||||
|
|
|
@ -4,7 +4,7 @@ from imagekit.processors import ResizeToFit
|
|||
|
||||
from reversion import revisions as reversion
|
||||
|
||||
from . import personalni as pm
|
||||
from personalni.models import Organizator
|
||||
|
||||
@reversion.register(ignore_duplicates=True)
|
||||
class Novinky(models.Model):
|
||||
|
@ -26,7 +26,7 @@ class Novinky(models.Model):
|
|||
],
|
||||
options={'quality': 95})
|
||||
|
||||
autor = models.ForeignKey(pm.Organizator, verbose_name='Autor novinky', null=True,
|
||||
autor = models.ForeignKey(Organizator, verbose_name='Autor novinky', null=True,
|
||||
on_delete=models.SET_NULL)
|
||||
|
||||
zverejneno = models.BooleanField('Zveřejněno', default=False)
|
||||
|
|
|
@ -10,11 +10,11 @@ from django.utils import timezone
|
|||
from django.conf import settings
|
||||
|
||||
from seminar.models import tvorba as am
|
||||
from seminar.models import personalni as pm
|
||||
from seminar.models import treenode as tm
|
||||
from seminar.models import base as bm
|
||||
|
||||
from seminar.utils import vzorecek_na_prepocet, inverze_vzorecku_na_prepocet
|
||||
from personalni.models import Resitel
|
||||
|
||||
|
||||
@reversion.register(ignore_duplicates=True)
|
||||
|
@ -34,7 +34,7 @@ class Reseni(bm.SeminarModelBase):
|
|||
problem = models.ManyToManyField(am.Problem, verbose_name='problém', help_text='Problém',
|
||||
through='Hodnoceni')
|
||||
|
||||
resitele = models.ManyToManyField(pm.Resitel, verbose_name='autoři řešení',
|
||||
resitele = models.ManyToManyField(Resitel, verbose_name='autoři řešení',
|
||||
help_text='Seznam autorů řešení', through='Reseni_Resitele')
|
||||
|
||||
|
||||
|
@ -229,7 +229,7 @@ class Reseni_Resitele(models.Model):
|
|||
# Interní ID
|
||||
id = models.AutoField(primary_key = True)
|
||||
|
||||
resitele = models.ForeignKey(pm.Resitel, verbose_name='řešitel', on_delete=models.PROTECT)
|
||||
resitele = models.ForeignKey(Resitel, verbose_name='řešitel', on_delete=models.PROTECT)
|
||||
|
||||
reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from unidecode import unidecode # Používám pro získání ID odkazu (ještě
|
|||
|
||||
from polymorphic.models import PolymorphicModel
|
||||
|
||||
from . import personalni as pm
|
||||
from personalni.models import Organizator
|
||||
|
||||
from .pomocne import Text
|
||||
|
||||
|
@ -166,7 +166,7 @@ class OrgTextNode(TreeNode):
|
|||
verbose_name = 'Organizátorský článek (Node)'
|
||||
verbose_name_plural = 'Organizátorské články (Node)'
|
||||
|
||||
organizator = models.ForeignKey(pm.Organizator,
|
||||
organizator = models.ForeignKey(Organizator,
|
||||
null=False,
|
||||
blank=False,
|
||||
on_delete=models.DO_NOTHING,
|
||||
|
|
|
@ -34,7 +34,7 @@ from polymorphic.models import PolymorphicModel
|
|||
from django.core.mail import EmailMessage
|
||||
from seminar.utils import aktivniResitele
|
||||
|
||||
from . import personalni as pm
|
||||
from personalni.models import Prijemce, Organizator
|
||||
|
||||
from .base import SeminarModelBase
|
||||
|
||||
|
@ -306,7 +306,7 @@ class Cislo(SeminarModelBase):
|
|||
resitele_vsichni.filter(zasilat_cislo_papirove=True))
|
||||
|
||||
paticka_prijemce = "---\nPokud tyto e-maily nechcete nadále dostávat, prosíme, ozvěte se nám na mam@matfyz.cz."
|
||||
posli(predmet, text_mailu + paticka_prijemce, pm.Prijemce.objects.filter(zasilat_cislo_emailem=True))
|
||||
posli(predmet, text_mailu + paticka_prijemce, Prijemce.objects.filter(zasilat_cislo_emailem=True))
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
|
@ -462,15 +462,15 @@ class Problem(SeminarModelBase,PolymorphicModel):
|
|||
poznamka = models.TextField('org poznámky (HTML)', blank=True,
|
||||
help_text='Neveřejný návrh úlohy, návrh řešení, text zadání, poznámky ...')
|
||||
|
||||
autor = models.ForeignKey(pm.Organizator, verbose_name='autor problému',
|
||||
autor = models.ForeignKey(Organizator, verbose_name='autor problému',
|
||||
related_name='autor_problemu_%(class)s', null=True, blank=True,
|
||||
on_delete=models.SET_NULL)
|
||||
|
||||
garant = models.ForeignKey(pm.Organizator, verbose_name='garant zadaného problému',
|
||||
garant = models.ForeignKey(Organizator, verbose_name='garant zadaného problému',
|
||||
related_name='garant_problemu_%(class)s', null=True, blank=True,
|
||||
on_delete=models.SET_NULL)
|
||||
|
||||
opravovatele = models.ManyToManyField(pm.Organizator, verbose_name='opravovatelé',
|
||||
opravovatele = models.ManyToManyField(Organizator, verbose_name='opravovatelé',
|
||||
blank=True, related_name='opravovatele_%(class)s')
|
||||
|
||||
kod = models.CharField('lokální kód', max_length=32, blank=True, default='',
|
||||
|
@ -691,7 +691,7 @@ class Pohadka(SeminarModelBase):
|
|||
id = models.AutoField(primary_key=True)
|
||||
|
||||
autor = models.ForeignKey(
|
||||
pm.Organizator,
|
||||
Organizator,
|
||||
verbose_name="Autor pohádky",
|
||||
|
||||
# Při nahrávání z TeXu není vyplnění vyžadováno, v adminu je
|
||||
|
@ -722,34 +722,3 @@ class Pohadka(SeminarModelBase):
|
|||
except ObjectDoesNotExist:
|
||||
# Neexistující *Node nemá smysl aktualizovat.
|
||||
pass
|
||||
|
||||
|
||||
@reversion.register(ignore_duplicates=True)
|
||||
class Nastaveni(SingletonModel):
|
||||
|
||||
class Meta:
|
||||
db_table = 'seminar_nastaveni'
|
||||
verbose_name = 'Nastavení semináře'
|
||||
|
||||
# aktualni_rocnik = models.ForeignKey(Rocnik, verbose_name='aktuální ročník',
|
||||
# null=False, on_delete=models.PROTECT)
|
||||
|
||||
aktualni_cislo = models.ForeignKey(Cislo, verbose_name='Aktuální číslo',
|
||||
null=False, on_delete=models.PROTECT)
|
||||
|
||||
cena_sous = models.IntegerField(null=False,
|
||||
verbose_name="Účastnický poplatek za soustředění",
|
||||
default=1000)
|
||||
|
||||
@property
|
||||
def aktualni_rocnik(self):
|
||||
return self.aktualni_cislo.rocnik
|
||||
|
||||
def __str__(self):
|
||||
return 'Nastavení semináře'
|
||||
|
||||
def admin_url(self):
|
||||
return reverse('admin:seminar_nastaveni_change', args=(self.id, ))
|
||||
|
||||
def verejne(self):
|
||||
return False
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from .models import OdpovedUcastnika, SpravnaOdpoved
|
||||
from .models import OdpovedUcastnika, SpravnaOdpoved, NapovezenoUcastnikovi, Napoveda
|
||||
|
||||
# Register your models here.
|
||||
|
||||
admin.site.register(OdpovedUcastnika)
|
||||
admin.site.register(SpravnaOdpoved)
|
||||
admin.site.register(Napoveda)
|
||||
admin.site.register(NapovezenoUcastnikovi)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django.core.exceptions import ValidationError
|
||||
from django.forms import ModelForm, Textarea
|
||||
from .models import OdpovedUcastnika, SpravnaOdpoved
|
||||
from .models import OdpovedUcastnika, SpravnaOdpoved, NapovezenoUcastnikovi, Napoveda
|
||||
|
||||
|
||||
class SifrovackaForm(ModelForm):
|
||||
|
@ -16,3 +16,15 @@ class SifrovackaForm(ModelForm):
|
|||
if SpravnaOdpoved.objects.filter(sifra=sifra).count() == 0:
|
||||
raise ValidationError("Tohle číslo šifry v databázi nemáme. Zkontrolujte si ho prosím.")
|
||||
return sifra
|
||||
|
||||
|
||||
class NapovedaForm(ModelForm):
|
||||
class Meta:
|
||||
model = NapovezenoUcastnikovi
|
||||
fields = ["sifra",]
|
||||
|
||||
def clean_sifra(self):
|
||||
sifra = self.cleaned_data.get('sifra')
|
||||
if Napoveda.objects.filter(sifra=sifra).count() == 0:
|
||||
raise ValidationError("K tomuto číslu šifry nemáme nápovědu. Zkontrolujte si ho prosím.")
|
||||
return sifra
|
||||
|
|
13
sifrovacka/migrations/0004_auto_20240312_2124.py
Normal file
13
sifrovacka/migrations/0004_auto_20240312_2124.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Generated by Django 4.2.8 on 2024-03-12 20:24
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sifrovacka', '0004_napoveda_napovezenoucastnikovi'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
65
sifrovacka/migrations/0004_napoveda_napovezenoucastnikovi.py
Normal file
65
sifrovacka/migrations/0004_napoveda_napovezenoucastnikovi.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
# Generated by Django 4.2.8 on 2024-04-14 12:57
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
(
|
||||
"seminar",
|
||||
"0114_related_name_se_zmenilo_a_django_chce_migraci_tak_dostane_migraci",
|
||||
),
|
||||
("sifrovacka", "0003_odpoveducastnika_uspech"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Napoveda",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("text", models.TextField()),
|
||||
("sifra", models.IntegerField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="NapovezenoUcastnikovi",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("sifra", models.IntegerField(verbose_name="Číslo šifry")),
|
||||
(
|
||||
"timestamp",
|
||||
models.DateTimeField(
|
||||
default=django.utils.timezone.now, verbose_name="Timestamp"
|
||||
),
|
||||
),
|
||||
(
|
||||
"resitel",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="seminar.resitel",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"ordering": ["-timestamp"],
|
||||
},
|
||||
),
|
||||
]
|
25
sifrovacka/migrations/0005_alter_odpoveducastnika_resitel.py
Normal file
25
sifrovacka/migrations/0005_alter_odpoveducastnika_resitel.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-19 21:35
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('personalni', '0003_initial'),
|
||||
('sifrovacka', '0004_auto_20240312_2124'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='odpoveducastnika',
|
||||
name='resitel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='personalni.resitel'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='napovezenoucastnikovi',
|
||||
name='resitel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='personalni.resitel'),
|
||||
),
|
||||
]
|
14
sifrovacka/migrations/0006_personalni_post_migrate.py
Normal file
14
sifrovacka/migrations/0006_personalni_post_migrate.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Generated by Django 4.2.11 on 2024-03-26 21:25
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sifrovacka', '0005_alter_odpoveducastnika_resitel'),
|
||||
('personalni', '0005_personalni_post_migrate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
|
@ -1,7 +1,7 @@
|
|||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
from seminar.models.personalni import Resitel
|
||||
from personalni.models import Resitel
|
||||
|
||||
|
||||
# Create your models here.
|
||||
|
@ -25,3 +25,20 @@ class SpravnaOdpoved(models.Model):
|
|||
|
||||
def __str__(self):
|
||||
return f"{self.sifra}: {self.odpoved}"
|
||||
|
||||
|
||||
class NapovezenoUcastnikovi(models.Model):
|
||||
class Meta:
|
||||
ordering = ["-timestamp"]
|
||||
|
||||
resitel = models.ForeignKey(Resitel, blank=False, null=False, on_delete=models.CASCADE)
|
||||
sifra = models.IntegerField("Číslo šifry", blank=False, null=False,)
|
||||
timestamp = models.DateTimeField("Timestamp", blank=False, null=False, default=timezone.now)
|
||||
|
||||
|
||||
class Napoveda(models.Model):
|
||||
text = models.TextField(blank=False, null=False,)
|
||||
sifra = models.IntegerField(blank=False, null=False,)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.sifra}: {self.text}"
|
||||
|
|
50
sifrovacka/templates/sifrovacka/napoveda.html
Normal file
50
sifrovacka/templates/sifrovacka/napoveda.html
Normal file
|
@ -0,0 +1,50 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<br>
|
||||
|
||||
<h1>{% block nadpis1a %}M&Mí šifrovačka{% endblock nadpis1a %}</h1>
|
||||
|
||||
<br>
|
||||
|
||||
<h2>Získat nápovědu k šifře:</h2>
|
||||
|
||||
<form action="{% url 'sifrovacka_napoveda' %}" method="post">
|
||||
<table class="form">
|
||||
{{form.non_field_errors}}
|
||||
{% for field in form %}
|
||||
<tr>
|
||||
<td>
|
||||
<label class="field-label{% if field.field.required %} field-required{% endif %}" for="{{ field.id_for_label }}">
|
||||
{{ field.label }}
|
||||
</label>
|
||||
|
||||
</td>
|
||||
|
||||
<td {% if field.help_text %} class="field-with-comment"{% endif %}>
|
||||
{{ field }}
|
||||
<span class="field-comment">{{ field.help_text|safe }}</span>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
|
||||
{% if field.errors %}
|
||||
<tr>
|
||||
<td colspan="2"><span class="field-error">{{ field.errors }}</span></td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% csrf_token %}
|
||||
|
||||
<input type="submit" value="Chci nápovědu">
|
||||
</form>
|
||||
|
||||
<p><a href="{% url 'sifrovacka' %}">Nechceme nápovědu, známe řešení!</a></p>
|
||||
|
||||
<p><a href="{% url 'sifrovacka_preskoceni' %}">Přeskoč šifru</a></p>
|
||||
|
||||
{% endblock content %}
|
23
sifrovacka/templates/sifrovacka/napovedy_list.html
Normal file
23
sifrovacka/templates/sifrovacka/napovedy_list.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{% block nadpis1a %}Šifrovačka vzaté nápovědy{% endblock nadpis1a %}</h1>
|
||||
|
||||
<table class="dosla_reseni">
|
||||
<tr>
|
||||
<th>Timestamp</th>
|
||||
<th>Řešitel</th>
|
||||
<th>Šifra</th>
|
||||
</tr>
|
||||
|
||||
{% for u in object_list %}
|
||||
<tr>
|
||||
<td>{{ u.timestamp }}</td>
|
||||
<td>{{ u.resitel }}</td>
|
||||
<td>{{ u.sifra }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% endblock content %}
|
54
sifrovacka/templates/sifrovacka/preskoceni.html
Normal file
54
sifrovacka/templates/sifrovacka/preskoceni.html
Normal file
|
@ -0,0 +1,54 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<br>
|
||||
|
||||
<h1>{% block nadpis1a %}M&Mí šifrovačka{% endblock nadpis1a %}</h1>
|
||||
|
||||
<br>
|
||||
|
||||
<h2>Přeskočit šifru:</h2>
|
||||
|
||||
<form action="{% url 'sifrovacka_preskoceni' %}" method="post">
|
||||
<table class="form">
|
||||
{{form.non_field_errors}}
|
||||
{% for field in form %}
|
||||
{% if field.id_for_label != "id_odpoved" %}
|
||||
<tr>
|
||||
<td>
|
||||
<label class="field-label{% if field.field.required %} field-required{% endif %}" for="{{ field.id_for_label }}">
|
||||
{{ field.label }}
|
||||
</label>
|
||||
|
||||
</td>
|
||||
|
||||
<td {% if field.help_text %} class="field-with-comment"{% endif %}>
|
||||
{{ field }}
|
||||
<span class="field-comment">{{ field.help_text|safe }}</span>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
|
||||
{% if field.errors %}
|
||||
<tr>
|
||||
<td colspan="2"><span class="field-error">{{ field.errors }}</span></td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ field.as_hidden }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% csrf_token %}
|
||||
|
||||
<input type="submit" value="Chceme další stanoviště bez vyřešení šifry">
|
||||
</form>
|
||||
|
||||
<p><a href="{% url 'sifrovacka' %}">Nechceme přeskočit, známe řešení!</a></p>
|
||||
|
||||
<p><a href="{% url 'sifrovacka_napoveda' %}">Nechceme přeskakovat, ale nápověda by se šikla.</a></p>
|
||||
|
||||
{% endblock content %}
|
|
@ -43,4 +43,8 @@
|
|||
<input type="submit" value="Tak pravím!">
|
||||
</form>
|
||||
|
||||
<p><a href="{% url 'sifrovacka_napoveda' %}">Získat nápovědu</a></p>
|
||||
|
||||
<p><a href="{% url 'sifrovacka_preskoceni' %}">Přeskoč šifru</a></p>
|
||||
|
||||
{% endblock content %}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from django.urls import path
|
||||
|
||||
from seminar.utils import org_required, resitel_or_org_required
|
||||
from .views import SifrovackaView, SifrovackaListView
|
||||
from .views import SifrovackaView, SifrovackaListView, NapovedaView, NapovedaListView, PreskoceniView
|
||||
|
||||
urlpatterns = [
|
||||
path(
|
||||
|
@ -14,4 +14,19 @@ urlpatterns = [
|
|||
org_required(SifrovackaListView.as_view()),
|
||||
name='sifrovacka_odpovedi'
|
||||
),
|
||||
path(
|
||||
'napoveda/',
|
||||
resitel_or_org_required(NapovedaView.as_view()),
|
||||
name='sifrovacka_napoveda'
|
||||
),
|
||||
path(
|
||||
'napovedy/',
|
||||
org_required(NapovedaListView.as_view()),
|
||||
name='sifrovacka_napovedy'
|
||||
),
|
||||
path(
|
||||
'preskoceni/',
|
||||
resitel_or_org_required(PreskoceniView.as_view()),
|
||||
name='sifrovacka_preskoceni'
|
||||
),
|
||||
]
|
||||
|
|
|
@ -2,9 +2,9 @@ from django.urls import reverse
|
|||
from django.views.generic import FormView, ListView
|
||||
|
||||
from seminar.views import formularOKView
|
||||
from .forms import SifrovackaForm
|
||||
from .models import OdpovedUcastnika, SpravnaOdpoved
|
||||
from seminar.models.personalni import Resitel
|
||||
from .forms import SifrovackaForm, NapovedaForm
|
||||
from .models import OdpovedUcastnika, SpravnaOdpoved, Napoveda, NapovezenoUcastnikovi
|
||||
from personalni.models import Resitel
|
||||
|
||||
|
||||
# Create your views here.
|
||||
|
@ -24,10 +24,47 @@ class SifrovackaView(FormView):
|
|||
|
||||
instance.uspech = True
|
||||
instance.save()
|
||||
|
||||
|
||||
return formularOKView(self.request, f'<h1>{sifra.skryty_text}</h1> <p><a href="{reverse("sifrovacka")}">Odevzdat další.</a></p><br><br><br>')
|
||||
|
||||
|
||||
class SifrovackaListView(ListView):
|
||||
template_name = 'sifrovacka/odpovedi_list.html'
|
||||
model = OdpovedUcastnika
|
||||
|
||||
|
||||
class NapovedaView(FormView):
|
||||
template_name = 'sifrovacka/napoveda.html'
|
||||
form_class = NapovedaForm
|
||||
|
||||
def form_valid(self, form):
|
||||
instance = form.save(commit=False)
|
||||
resitel = Resitel.objects.get(osoba__user=self.request.user)
|
||||
instance.resitel = resitel
|
||||
|
||||
if NapovezenoUcastnikovi.objects.filter(resitel=resitel, sifra=instance.sifra).first() is None:
|
||||
instance.save()
|
||||
|
||||
napoveda = Napoveda.objects.filter(sifra=instance.sifra).first()
|
||||
return formularOKView(self.request, f'<h1>Nápověda k šifře číslo {instance.sifra} je:</h1><p>{napoveda.text}</p> <p><a href="{reverse("sifrovacka")}">Odevzdat řešení.</a></p><br><br><br>')
|
||||
|
||||
|
||||
class NapovedaListView(ListView):
|
||||
template_name = 'sifrovacka/napovedy_list.html'
|
||||
model = NapovezenoUcastnikovi
|
||||
|
||||
|
||||
class PreskoceniView(FormView):
|
||||
template_name = 'sifrovacka/preskoceni.html'
|
||||
form_class = SifrovackaForm
|
||||
initial = {"odpoved": "=======PŘESKOČENO======="}
|
||||
|
||||
def form_valid(self, form):
|
||||
instance = form.save(commit=False)
|
||||
instance.odpoved = "=======PŘESKOČENO======="
|
||||
resitel = Resitel.objects.get(osoba__user=self.request.user)
|
||||
instance.resitel = resitel
|
||||
instance.save()
|
||||
sifra = SpravnaOdpoved.objects.filter(sifra=instance.sifra).first() # FIXME co když je více "správných" odpovědí?
|
||||
|
||||
return formularOKView(self.request, f'<h1>{sifra.skryty_text}</h1> <p><a href="{reverse("sifrovacka")}">Zpět na odevzdávátko.</a></p><br><br><br>')
|
||||
|
|
|
@ -2,7 +2,7 @@ from django.contrib import admin
|
|||
from django.forms import widgets
|
||||
from django.db import models
|
||||
|
||||
from seminar.models import soustredeni as m
|
||||
import soustredeni.models as m
|
||||
|
||||
|
||||
class SoustredeniUcastniciInline(admin.TabularInline):
|
||||
|
|
122
soustredeni/migrations/0001_split_from_seminar.py
Normal file
122
soustredeni/migrations/0001_split_from_seminar.py
Normal file
|
@ -0,0 +1,122 @@
|
|||
# Generated by Django 4.2.11 on 2024-04-30 22:53
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import soustredeni.models
|
||||
|
||||
def nastav_nove_contenttypes(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
for m in ('konfera', 'soustredeni', 'soustredeni_ucastnici', 'soustredeni_organizatori', 'konfery_ucastnici'):
|
||||
oct = ContentType.objects.filter(app_label='seminar', model=m)
|
||||
oct.update(app_label='soustredeni')
|
||||
|
||||
def nastav_stare_contenttypes(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
for m in ('konfera', 'soustredeni', 'soustredeni_ucastnici', 'soustredeni_organizatori', 'konfery_ucastnici'):
|
||||
nct = ContentType.objects.filter(app_label='soustredeni', model=m)
|
||||
nct.update(app_label='seminar')
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0123_soustredeni_unmanage'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(nastav_nove_contenttypes, nastav_stare_contenttypes),
|
||||
|
||||
migrations.CreateModel(
|
||||
name='Konfera',
|
||||
fields=[
|
||||
('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.problem')),
|
||||
('anotace', models.TextField(blank=True, help_text='Popis, o čem bude konfera.', verbose_name='anotace')),
|
||||
('abstrakt', models.TextField(blank=True, help_text='Abstrakt konfery tak, jak byl uveden ve sborníku', verbose_name='abstrakt')),
|
||||
('typ_prezentace', models.CharField(choices=[('veletrh', 'Veletrh (postery)'), ('prezentace', 'Prezentace (přednáška)')], default='veletrh', max_length=16, verbose_name='typ prezentace')),
|
||||
('prezentace', models.FileField(blank=True, help_text='Prezentace nebo fotka posteru', upload_to=soustredeni.models.generate_filename_konfera, verbose_name='prezentace')),
|
||||
('materialy', models.FileField(blank=True, help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=soustredeni.models.generate_filename_konfera, verbose_name='materialy')),
|
||||
('soustredeni', models.ForeignKey(to='soustredeni.soustredeni', verbose_name='soustředění', on_delete=models.SET_NULL, null=True, related_name='konfery')),
|
||||
('ucastnici', models.ManyToManyField(help_text='Seznam účastníků konfery', through='soustredeni.Konfery_Ucastnici', to='personalni.resitel', verbose_name='účastníci konfery')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Konfera',
|
||||
'verbose_name_plural': 'Konfery',
|
||||
'db_table': 'seminar_konfera',
|
||||
'managed': False,
|
||||
},
|
||||
bases=('seminar.problem',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Konfery_Ucastnici',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')),
|
||||
('resitel', models.ForeignKey(to='personalni.resitel', verbose_name='řešitel', on_delete=models.PROTECT)),
|
||||
('konfera', models.ForeignKey(to='soustredeni.konfera', verbose_name='konfera', on_delete=models.CASCADE)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Účast na konfeře',
|
||||
'verbose_name_plural': 'Účasti na konfeře',
|
||||
'db_table': 'seminar_konfery_ucastnici',
|
||||
'ordering': ['konfera', 'resitel'],
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Soustredeni',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('datum_zacatku', models.DateField(blank=True, help_text='První den soustředění', null=True, verbose_name='datum začátku')),
|
||||
('datum_konce', models.DateField(blank=True, help_text='Poslední den soustředění', null=True, verbose_name='datum konce')),
|
||||
('verejne_db', models.BooleanField(db_column='verejne', default=False, verbose_name='soustředění zveřejněno')),
|
||||
('misto', models.CharField(blank=True, default='', help_text='Místo (název obce, volitelně též objektu', max_length=256, verbose_name='místo soustředění')),
|
||||
('text', models.TextField(blank=True, default='', verbose_name='text k soustředění (HTML)')),
|
||||
('typ', models.CharField(choices=[('jarni', 'Jarní soustředění'), ('podzimni', 'Podzimní soustředění'), ('vikend', 'Víkendový sraz'), ('vylet', 'Výlet')], default='podzimni', max_length=16, verbose_name='typ akce')),
|
||||
('exportovat', models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)', verbose_name='export do AESOPa')),
|
||||
('rocnik', models.ForeignKey(to='seminar.rocnik', verbose_name='ročník', related_name='soustredeni', on_delete=models.PROTECT)),
|
||||
('organizatori', models.ManyToManyField(help_text='Seznam organizátorů soustředění', through='soustredeni.Soustredeni_Organizatori', to='personalni.organizator', verbose_name='Organizátoři soustředění')),
|
||||
('ucastnici', models.ManyToManyField(help_text='Seznam účastníků soustředění', through='soustredeni.Soustredeni_Ucastnici', to='personalni.resitel', verbose_name='účastníci soustředění')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Soustředění',
|
||||
'verbose_name_plural': 'Soustředění',
|
||||
'db_table': 'seminar_soustredeni',
|
||||
'ordering': ['-rocnik__rocnik', '-datum_zacatku'],
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Soustredeni_Organizatori',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti organizátora (plain text)', verbose_name='neveřejná poznámka')),
|
||||
('organizator', models.ForeignKey(to='personalni.organizator', verbose_name='organizátor', on_delete=models.PROTECT)),
|
||||
('soustredeni', models.ForeignKey(to='soustredeni.soustredeni', verbose_name='soustředění', on_delete=models.PROTECT)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Účast organizátorů na soustředění',
|
||||
'verbose_name_plural': 'Účasti organizátorů na soustředění',
|
||||
'db_table': 'seminar_soustredeni_organizatori',
|
||||
'ordering': ['soustredeni', 'organizator'],
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Soustredeni_Ucastnici',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')),
|
||||
('resitel', models.ForeignKey(to='personalni.resitel', verbose_name='řešitel', on_delete=models.PROTECT)),
|
||||
('soustredeni', models.ForeignKey(to='soustredeni.soustredeni', verbose_name='soustředění', on_delete=models.PROTECT)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Účast na soustředění',
|
||||
'verbose_name_plural': 'Účasti na soustředění',
|
||||
'db_table': 'seminar_soustredeni_ucastnici',
|
||||
'ordering': ['soustredeni', 'resitel'],
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
]
|
34
soustredeni/migrations/0002_manage_soustredeni.py
Normal file
34
soustredeni/migrations/0002_manage_soustredeni.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Generated by Django 4.2.11 on 2024-05-01 13:18
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('soustredeni', '0001_split_from_seminar'),
|
||||
('seminar', '0124_remove_sous_from_seminar'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='konfera',
|
||||
options={'verbose_name': 'Konfera', 'verbose_name_plural': 'Konfery'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='konfery_ucastnici',
|
||||
options={'ordering': ['konfera', 'resitel'], 'verbose_name': 'Účast na konfeře', 'verbose_name_plural': 'Účasti na konfeře'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='soustredeni',
|
||||
options={'ordering': ['-rocnik__rocnik', '-datum_zacatku'], 'verbose_name': 'Soustředění', 'verbose_name_plural': 'Soustředění'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='soustredeni_organizatori',
|
||||
options={'ordering': ['soustredeni', 'organizator'], 'verbose_name': 'Účast organizátorů na soustředění', 'verbose_name_plural': 'Účasti organizátorů na soustředění'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='soustredeni_ucastnici',
|
||||
options={'ordering': ['soustredeni', 'resitel'], 'verbose_name': 'Účast na soustředění', 'verbose_name_plural': 'Účasti na soustředění'},
|
||||
),
|
||||
]
|
13
soustredeni/migrations/0003_post_split_soustredeni.py
Normal file
13
soustredeni/migrations/0003_post_split_soustredeni.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Generated by Django 4.2.11 on 2024-05-01 13:35
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('soustredeni', '0002_manage_soustredeni'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
|
@ -8,9 +8,9 @@ from reversion import revisions as reversion
|
|||
|
||||
from django.conf import settings
|
||||
|
||||
from . import personalni as pm
|
||||
from personalni.models import Resitel, Organizator
|
||||
|
||||
from .base import SeminarModelBase
|
||||
from seminar.models.base import SeminarModelBase
|
||||
from seminar.models import tvorba as am
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -42,10 +42,10 @@ class Soustredeni(SeminarModelBase):
|
|||
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í',
|
||||
ucastnici = models.ManyToManyField(Resitel, verbose_name='účastníci soustředění',
|
||||
help_text='Seznam účastníků soustředění', through='Soustredeni_Ucastnici')
|
||||
|
||||
organizatori = models.ManyToManyField(pm.Organizator,
|
||||
organizatori = models.ManyToManyField(Organizator,
|
||||
verbose_name='Organizátoři soustředění',
|
||||
help_text='Seznam organizátorů soustředění',
|
||||
through='Soustredeni_Organizatori')
|
||||
|
@ -92,7 +92,7 @@ class Soustredeni_Ucastnici(SeminarModelBase):
|
|||
# Interní ID
|
||||
id = models.AutoField(primary_key = True)
|
||||
|
||||
resitel = models.ForeignKey(pm.Resitel, verbose_name='řešitel', on_delete=models.PROTECT)
|
||||
resitel = models.ForeignKey(Resitel, verbose_name='řešitel', on_delete=models.PROTECT)
|
||||
|
||||
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
||||
on_delete=models.PROTECT)
|
||||
|
@ -118,7 +118,7 @@ class Soustredeni_Organizatori(SeminarModelBase):
|
|||
# Interní ID
|
||||
id = models.AutoField(primary_key = True)
|
||||
|
||||
organizator = models.ForeignKey(pm.Organizator, verbose_name='organizátor',
|
||||
organizator = models.ForeignKey(Organizator, verbose_name='organizátor',
|
||||
on_delete=models.PROTECT)
|
||||
|
||||
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
||||
|
@ -163,7 +163,7 @@ class Konfera(am.Problem):
|
|||
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',
|
||||
ucastnici = models.ManyToManyField(Resitel, verbose_name='účastníci konfery',
|
||||
help_text='Seznam účastníků konfery', through='Konfery_Ucastnici')
|
||||
|
||||
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
|
||||
|
@ -204,7 +204,7 @@ class Konfery_Ucastnici(models.Model):
|
|||
# Interní ID
|
||||
id = models.AutoField(primary_key = True)
|
||||
|
||||
resitel = models.ForeignKey(pm.Resitel, verbose_name='řešitel', on_delete=models.PROTECT)
|
||||
resitel = models.ForeignKey(Resitel, verbose_name='řešitel', on_delete=models.PROTECT)
|
||||
|
||||
konfera = models.ForeignKey(Konfera, verbose_name='konfera', on_delete=models.CASCADE)
|
||||
|
52
split-apps-meta/create-ct-hack.py
Normal file
52
split-apps-meta/create-ct-hack.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Správná migrace vypadá takto:
|
||||
# Generated by Django 3.2.23 on 2023-12-11 19:19
|
||||
|
||||
def nastav_nove_contenttypes(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
old_ct = ContentType.objects.filter(app_label='seminar', model='nastaveni')
|
||||
# Pozn: tohle může být prázdné (pokud Django nedostalo signál o dokončených migracích, např. při vyrábění databáze z nuly)
|
||||
# Ale .update to nevadí…
|
||||
old_ct.update(app_label='various')
|
||||
|
||||
def nastav_stare_contenttypes(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
new_ct = ContentType.objects.filter(app_label='various', model='nastaveni')
|
||||
new_ct.update(app_label='seminar')
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0115_alter_nastaveni_options'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Nastaveni',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('cena_sous', models.IntegerField(default=1000, verbose_name='Účastnický poplatek za soustředění')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Nastavení semináře',
|
||||
'db_table': 'seminar_nastaveni',
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.RunPython(nastav_nove_contenttypes, nastav_stare_contenttypes),
|
||||
]
|
||||
|
||||
|
||||
|
||||
#Hack: zkrácení
|
||||
def nastav_nove_contenttypes(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
for m in ('resitel', 'organizator', 'osoba', 'skola', 'prijemce'):
|
||||
ContentType.objects.filter(app_label='seminar', model=m).update(app_label='personalni')
|
||||
|
||||
def nastav_stare_contenttypes(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
for m in ('resitel', 'organizator', 'osoba', 'skola', 'prijemce'):
|
||||
ContentType.objects.filter(app_label='personalni', model=m).update(app_label='seminar')
|
||||
|
9
split-apps-meta/create.notes
Normal file
9
split-apps-meta/create.notes
Normal file
|
@ -0,0 +1,9 @@
|
|||
Prostě zkopírovat vedle, s původními (=správnými) related names.
|
||||
(Případně opravit *všechny* relativní importy)
|
||||
makemigrations
|
||||
! Doplnit hack kolem content-types (jako první operace při migraci)
|
||||
! Doplnit ForeignKeys (Vypadá to, že se dá vesměs zkopírovat předpis z models.py, jen místo prvního fieldu dát `to='app.model'. Dokonce asi funguje použít už novou aplikaci pro vazby v rámci aplikace.)
|
||||
To samé s ManyToManyFieldy (through= musí taky být 'app.model')
|
||||
(Zdá se, že jde dobastlit tuhle migraci polozpětně – doplnit co chybělo až podle toho, co vygeneruje migrace po zamanagování nového modelu.)
|
||||
doplnit závislost na unmanage
|
||||
migrate
|
9
split-apps-meta/delete.notes
Normal file
9
split-apps-meta/delete.notes
Normal file
|
@ -0,0 +1,9 @@
|
|||
Prostě to smazat.
|
||||
makemigrations
|
||||
Kromě triviální smazání modelů se smažou i jejich vazby, to je snad OK.
|
||||
(Hypotéza: kvůli konzistenčním kontrolám v DB?)
|
||||
Doplnit vazby na relinky a vznik nového modelu
|
||||
migrate
|
||||
a doufat :-P
|
||||
|
||||
(Pozor: pokud něco (JSON serializace, data/… atp.) má starý identifikátor modelu, tak se to teď rozbije.)
|
6
split-apps-meta/dummy_migration.py
Normal file
6
split-apps-meta/dummy_migration.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from django.db import migrations
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('APP', 'MIGR'),
|
||||
]
|
||||
operations = []
|
4
split-apps-meta/manage.notes
Normal file
4
split-apps-meta/manage.notes
Normal file
|
@ -0,0 +1,4 @@
|
|||
1. smazat `managed = False`
|
||||
2. makemigrations
|
||||
Vazba na delete!
|
||||
3. migrate
|
6
split-apps-meta/other
Normal file
6
split-apps-meta/other
Normal file
|
@ -0,0 +1,6 @@
|
|||
admin
|
||||
práva
|
||||
aplikovat práva
|
||||
orgorozcestník a další reverzované urls
|
||||
|
||||
výhledově smazat ze seminare
|
2
split-apps-meta/post
Normal file
2
split-apps-meta/post
Normal file
|
@ -0,0 +1,2 @@
|
|||
dummy migrace v novém modelu
|
||||
dummy migrace v semináři a ostatních, závisející na té nové migraci.
|
3
split-apps-meta/pre.sh
Normal file
3
split-apps-meta/pre.sh
Normal file
|
@ -0,0 +1,3 @@
|
|||
for app in whatever I want; do
|
||||
./manage.py makemigrations --empty $app
|
||||
vim seminar/migrations/whatever.py # add the other as depends.
|
5
split-apps-meta/relink.notes
Normal file
5
split-apps-meta/relink.notes
Normal file
|
@ -0,0 +1,5 @@
|
|||
Přepsat všechny odkazy v sousedních aplikacích na novou aplikaci
|
||||
Naincludovat nové modely v seminar.models kvůli views
|
||||
makemigrations
|
||||
Zkontrolovat přítomnost závislosti na create!
|
||||
migrate
|
24
split-apps-meta/unmanage.notes
Normal file
24
split-apps-meta/unmanage.notes
Normal file
|
@ -0,0 +1,24 @@
|
|||
vim seminar/models/whatever
|
||||
Model.Meta.managed = False
|
||||
Model.field.related_name = Model.related_name + '_old' # až vyrobíme nový objekt, tak nesmí kolidovat.
|
||||
# related_name se vyhodnocuje za běhu, takže pokud nic nespustíme (celý
|
||||
# blok migrací spustíme najednou), tak nám nevadí, že v tuhle chvíli nefunguje půlka views ap :-)
|
||||
Nastavit nějak i všechny další závislostní fieldy (mají defaultní related_name!)
|
||||
- ManyToManyF, OneToOneF, ForeignKey, …
|
||||
Nevím proč, ale když nebyly unikátní, tak se to potlouklo::
|
||||
seminar.Prijemce.osoba: (fields.E304) Reverse accessor 'Osoba.osoba_old' for 'seminar.Prijemce.osoba' clashes with reverse accessor for 'seminar.Resitel.osoba'.
|
||||
HINT: Add or change a related_name argument to the definition for 'seminar.Prijemce.osoba' or 'seminar.Resitel.osoba'.
|
||||
seminar.Prijemce.osoba: (fields.E305) Reverse query name for 'seminar.Prijemce.osoba' clashes with reverse query name for 'seminar.Resitel.osoba'.
|
||||
HINT: Add or change a related_name argument to the definition for 'seminar.Prijemce.osoba' or 'seminar.Resitel.osoba'.
|
||||
seminar.Resitel.osoba: (fields.E304) Reverse accessor 'Osoba.osoba_old' for 'seminar.Resitel.osoba' clashes with reverse accessor for 'seminar.Prijemce.osoba'.
|
||||
HINT: Add or change a related_name argument to the definition for 'seminar.Resitel.osoba' or 'seminar.Prijemce.osoba'.
|
||||
seminar.Resitel.osoba: (fields.E305) Reverse query name for 'seminar.Resitel.osoba' clashes with reverse query name for 'seminar.Prijemce.osoba'.
|
||||
HINT: Add or change a related_name argument to the definition for 'seminar.Resitel.osoba' or 'seminar.Prijemce.osoba'.
|
||||
Snadné řešení: dočasné related names mít unikátní. Stejně to nikoho nezajímá.
|
||||
!! Zkontrolovat, že všechno má nastavenou db_table (jinak se to potom pokusí vybastlit jméno tabulky podle aplikace…)
|
||||
Pro tip: related names nejsou součástí DB schématu, takže když se tohle opraví později (typicky při create spadne makemigrations), nevadí to a nemělo by být potřeba měnit migrace).
|
||||
Pro multi-table inheritance je potřeba explicitně přidat 1to1Field s parent_link=True (<https://docs.djangoproject.com/en/5.0/topics/db/models/#specifying-the-parent-link-field>)
|
||||
Je potřeba to udělat správně (třeba nemít FK), migrace potřeba není, protože je to stejně unmanaged…
|
||||
|
||||
makemigrations, bez úprav
|
||||
migrate?
|
40
various/migrations/0001_initial.py
Normal file
40
various/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Generated by Django 3.2.23 on 2023-12-11 19:19
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
def nastav_nove_contenttypes(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
old_ct = ContentType.objects.filter(app_label='seminar', model='nastaveni')
|
||||
# Pozn: tohle může být prázdné (pokud Django nedostalo signál o dokončených migracích, např. při vyrábění databáze z nuly)
|
||||
# Ale .update to nevadí…
|
||||
old_ct.update(app_label='various')
|
||||
|
||||
def nastav_stare_contenttypes(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
new_ct = ContentType.objects.filter(app_label='various', model='nastaveni')
|
||||
new_ct.update(app_label='seminar')
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('seminar', '0115_alter_nastaveni_options'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Nastaveni',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('cena_sous', models.IntegerField(default=1000, verbose_name='Účastnický poplatek za soustředění')),
|
||||
('aktualni_cislo', models.ForeignKey(null=True, on_delete=models.deletion.PROTECT, to='seminar.cislo', verbose_name='Aktuální číslo')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Nastavení semináře',
|
||||
'db_table': 'seminar_nastaveni',
|
||||
'managed': False,
|
||||
},
|
||||
),
|
||||
migrations.RunPython(nastav_nove_contenttypes, nastav_stare_contenttypes),
|
||||
]
|
18
various/migrations/0002_alter_nastaveni_options.py
Normal file
18
various/migrations/0002_alter_nastaveni_options.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.23 on 2023-12-11 19:30
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('various', '0001_initial'),
|
||||
('seminar', '0116_delete_nastaveni'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='nastaveni',
|
||||
options={'verbose_name': 'Nastavení semináře'},
|
||||
),
|
||||
]
|
40
various/migrations/0003_fix_permissions.py
Normal file
40
various/migrations/0003_fix_permissions.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Generated by Django 3.2.23 on 2023-12-11 19:40
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
def oprav_prava_k_nastaveni(apps, schema_editor):
|
||||
# Tohle je trošku hnus, nešlo by to snáz?
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
Permission = apps.get_model('auth', 'Permission')
|
||||
Group = apps.get_model('auth', 'Group')
|
||||
old_ct = ContentType.objects.get_by_natural_key('seminar', 'nastaveni')
|
||||
new_ct = ContentType.objects.get_by_natural_key('various', 'nastaveni')
|
||||
old_perms = Permission.objects.filter(content_type=old_ct)
|
||||
new_perms = Permission.objects.filter(content_type=new_ct)
|
||||
for g in Group.objects.filter(permissions__in=old_perms):
|
||||
old_codenames = Permission.objects.filter(group__in=[g], content_type=old_ct).values('codename')
|
||||
g.permissions.add(*new_perms.filter(codename__in=old_codenames))
|
||||
g.permissions.remove(*old_perms)
|
||||
|
||||
def obnov_prava_k_nastaveni(apps, schema_editor):
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
Permission = apps.get_model('auth', 'Permission')
|
||||
Group = apps.get_model('auth', 'Group')
|
||||
old_ct = ContentType.objects.get_by_natural_key('seminar', 'nastaveni')
|
||||
new_ct = ContentType.objects.get_by_natural_key('various', 'nastaveni')
|
||||
old_perms = Permission.objects.filter(content_type=old_ct)
|
||||
new_perms = Permission.objects.filter(content_type=new_ct)
|
||||
for g in Group.objects.filter(permissions__in=old_perms):
|
||||
new_codenames = Permission.objects.filter(group__in=[g], content_type=new_ct).values('codename')
|
||||
g.permissions.add(*old_perms.filter(codename__in=new_codenames))
|
||||
g.permissions.remove(*new_perms)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('various', '0002_alter_nastaveni_options'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
|
@ -1,3 +1,39 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
from reversion import revisions as reversion
|
||||
from solo.models import SingletonModel
|
||||
|
||||
from seminar.models import Cislo
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
@reversion.register(ignore_duplicates=True)
|
||||
class Nastaveni(SingletonModel):
|
||||
|
||||
class Meta:
|
||||
db_table = 'seminar_nastaveni'
|
||||
verbose_name = 'Nastavení semináře'
|
||||
|
||||
# aktualni_rocnik = models.ForeignKey(Rocnik, verbose_name='aktuální ročník',
|
||||
# null=False, on_delete=models.PROTECT)
|
||||
|
||||
aktualni_cislo = models.ForeignKey(Cislo, verbose_name='Aktuální číslo',
|
||||
null=True, blank=False, on_delete=models.PROTECT,
|
||||
)
|
||||
|
||||
cena_sous = models.IntegerField(null=False,
|
||||
verbose_name="Účastnický poplatek za soustředění",
|
||||
default=1000)
|
||||
|
||||
@property
|
||||
def aktualni_rocnik(self):
|
||||
return self.aktualni_cislo.rocnik
|
||||
|
||||
def __str__(self):
|
||||
return 'Nastavení semináře'
|
||||
|
||||
def admin_url(self):
|
||||
return reverse('admin:seminar_nastaveni_change', args=(self.id, ))
|
||||
|
||||
def verejne(self):
|
||||
return False
|
||||
|
|
|
@ -6,18 +6,18 @@ class MailTagsTest(TestCase):
|
|||
"""Testuje template tagy ohledně mailů."""
|
||||
def test_maillink(self):
|
||||
# Tohle nedává smysl dělit do víc funkcí, bylo by v nich víc boilerplatu než užitečného kódu.
|
||||
self.assertEquals(maillink('Hello', to='some@body.test'), r'<a href="mailto:some@body.test">Hello</a>')
|
||||
self.assertEquals(maillink('Hello', to=['some@body.test']), r'<a href="mailto:some@body.test">Hello</a>')
|
||||
self.assertEquals(
|
||||
self.assertEqual(maillink('Hello', to='some@body.test'), r'<a href="mailto:some@body.test">Hello</a>')
|
||||
self.assertEqual(maillink('Hello', to=['some@body.test']), r'<a href="mailto:some@body.test">Hello</a>')
|
||||
self.assertEqual(
|
||||
maillink('Hello', to=['alice@test.test', 'bob@jinde.test']),
|
||||
r'<a href="mailto:alice@test.test,bob@jinde.test">Hello</a>',
|
||||
)
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
maillink('Hello', to='some@body.test', attrs='class="trida" id="id"'),
|
||||
r'<a href="mailto:some@body.test" class="trida" id="id">Hello</a>',
|
||||
)
|
||||
# Následující test toho testuje moc zároveň, měly by předcházet dedikované testy… (kašlu na ně :-P)
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
maillink('Text odkazu', to='prijemce@wtf.test', subject="Předmět", body="Čau"),
|
||||
r'<a href="mailto:prijemce@wtf.test?subject=P%C5%99edm%C4%9Bt&body=%C4%8Cau">Text odkazu</a>',
|
||||
)
|
||||
|
@ -25,10 +25,10 @@ class MailTagsTest(TestCase):
|
|||
self.assertRaises(TypeError, lambda: maillink()) # Nemá text, takže to shodí python
|
||||
|
||||
def test_mailurl(self):
|
||||
self.assertEquals(mailurl(to='some@body.test'), r'mailto:some@body.test')
|
||||
self.assertEquals(mailurl(to=['some@body.test']), r'mailto:some@body.test')
|
||||
self.assertEquals(mailurl(to=['alice@test.test', 'bob@jinde.test']), r'mailto:alice@test.test,bob@jinde.test')
|
||||
self.assertEquals(
|
||||
self.assertEqual(mailurl(to='some@body.test'), r'mailto:some@body.test')
|
||||
self.assertEqual(mailurl(to=['some@body.test']), r'mailto:some@body.test')
|
||||
self.assertEqual(mailurl(to=['alice@test.test', 'bob@jinde.test']), r'mailto:alice@test.test,bob@jinde.test')
|
||||
self.assertEqual(
|
||||
mailurl(to='some@body.test', body='Tělo', subject='Předmět'),
|
||||
r'mailto:some@body.test?subject=P%C5%99edm%C4%9Bt&body=T%C4%9Blo',
|
||||
)
|
||||
|
@ -48,7 +48,7 @@ class MailTagsTest(TestCase):
|
|||
# TODO: Vyzkoušet i víc adresátů. (Nepamatuji si z hlavy syntaxi…)
|
||||
r'{% maillink "Text" to="alice@test.test" subject="Oprava řešení" %}'
|
||||
)
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
render_template(template),
|
||||
r'<a href="mailto:alice@test.test?subject=Oprava%20%C5%99e%C5%A1en%C3%AD">Text</a>',
|
||||
)
|
||||
|
@ -57,4 +57,4 @@ class MailTagsTest(TestCase):
|
|||
r'{% load mail %}'
|
||||
r'{% mailurl to="alice@test.test" subject="Čau Alice" %}'
|
||||
)
|
||||
self.assertEquals(render_template(mailurltemplate), r'mailto:alice@test.test?subject=%C4%8Cau%20Alice')
|
||||
self.assertEqual(render_template(mailurltemplate), r'mailto:alice@test.test?subject=%C4%8Cau%20Alice')
|
||||
|
|
Loading…
Reference in a new issue