Browse Source

Merge branch 'master' into reforma_pohlavi

pull/49/head
Pavel Turinský 6 months ago
parent
commit
37f988f478
  1. 3
      api/tests/test_skola_autocomplete.py
  2. 76
      deploy_v2/admin_org_prava.json
  3. 13
      galerie/migrations/0011_pre_split_soustredeni.py
  4. 20
      galerie/migrations/0012_soustredeni_relink.py
  5. 14
      galerie/migrations/0013_post_split_soustredeni.py
  6. 2
      galerie/models.py
  7. 13
      korektury/migrations/0021_auto_20240312_2124.py
  8. 30
      korektury/migrations/0022_alter_komentar_autor_alter_korekturovanepdf_org_and_more.py
  9. 14
      korektury/migrations/0023_personalni_post_migrate.py
  10. 2
      korektury/models.py
  11. 13
      personalni/migrations/0002_auto_20240312_2118.py
  12. 146
      personalni/migrations/0003_initial.py
  13. 34
      personalni/migrations/0004_alter_organizator_options_alter_osoba_options_and_more.py
  14. 13
      personalni/migrations/0005_personalni_post_migrate.py
  15. 13
      personalni/migrations/0006_pre_split_soustredeni.py
  16. 28
      personalni/models.py
  17. 18
      personalni/templates/personalni/profil/orgorozcestnik.html
  18. 13
      prednasky/migrations/0013_auto_20240312_2124.py
  19. 20
      prednasky/migrations/0014_alter_prednaska_org.py
  20. 14
      prednasky/migrations/0015_personalni_post_migrate.py
  21. 13
      prednasky/migrations/0016_pre_split_soustredeni.py
  22. 20
      prednasky/migrations/0017_soustredeni_relink.py
  23. 14
      prednasky/migrations/0018_post_split_soustredeni.py
  24. 3
      prednasky/models.py
  25. 17
      seminar/migrations/0115_alter_nastaveni_options.py
  26. 17
      seminar/migrations/0116_delete_nastaveni.py
  27. 16
      seminar/migrations/0117_auto_20240312_2125.py
  28. 33
      seminar/migrations/0118_alter_organizator_options_alter_osoba_options_and_more.py
  29. 85
      seminar/migrations/0119_alter_konfera_ucastnici_and_more.py
  30. 52
      seminar/migrations/0120_remove_osoba_user_remove_prijemce_osoba_and_more.py
  31. 14
      seminar/migrations/0121_personalni_post_migrate.py
  32. 16
      seminar/migrations/0122_pre_split_soustredeni.py
  33. 33
      seminar/migrations/0123_soustredeni_unmanage.py
  34. 67
      seminar/migrations/0124_remove_sous_from_seminar.py
  35. 14
      seminar/migrations/0125_post_split_soustredeni.py
  36. 9
      seminar/models/__init__.py
  37. 4
      seminar/models/novinky.py
  38. 6
      seminar/models/odevzdavatko.py
  39. 4
      seminar/models/treenode.py
  40. 43
      seminar/models/tvorba.py
  41. 4
      sifrovacka/admin.py
  42. 14
      sifrovacka/forms.py
  43. 13
      sifrovacka/migrations/0004_auto_20240312_2124.py
  44. 65
      sifrovacka/migrations/0004_napoveda_napovezenoucastnikovi.py
  45. 25
      sifrovacka/migrations/0005_alter_odpoveducastnika_resitel.py
  46. 14
      sifrovacka/migrations/0006_personalni_post_migrate.py
  47. 19
      sifrovacka/models.py
  48. 50
      sifrovacka/templates/sifrovacka/napoveda.html
  49. 23
      sifrovacka/templates/sifrovacka/napovedy_list.html
  50. 54
      sifrovacka/templates/sifrovacka/preskoceni.html
  51. 4
      sifrovacka/templates/sifrovacka/sifrovacka.html
  52. 17
      sifrovacka/urls.py
  53. 43
      sifrovacka/views.py
  54. 2
      soustredeni/admin.py
  55. 122
      soustredeni/migrations/0001_split_from_seminar.py
  56. 34
      soustredeni/migrations/0002_manage_soustredeni.py
  57. 13
      soustredeni/migrations/0003_post_split_soustredeni.py
  58. 16
      soustredeni/models.py
  59. 52
      split-apps-meta/create-ct-hack.py
  60. 9
      split-apps-meta/create.notes
  61. 9
      split-apps-meta/delete.notes
  62. 6
      split-apps-meta/dummy_migration.py
  63. 4
      split-apps-meta/manage.notes
  64. 6
      split-apps-meta/other
  65. 2
      split-apps-meta/post
  66. 3
      split-apps-meta/pre.sh
  67. 5
      split-apps-meta/relink.notes
  68. 24
      split-apps-meta/unmanage.notes
  69. 40
      various/migrations/0001_initial.py
  70. 18
      various/migrations/0002_alter_nastaveni_options.py
  71. 40
      various/migrations/0003_fix_permissions.py
  72. 38
      various/models.py
  73. 22
      various/tests.py

3
api/tests/test_skola_autocomplete.py

@ -1,9 +1,10 @@
from django.test import TestCase from django.test import TestCase, tag
from django.urls import reverse from django.urls import reverse
import seminar.models as m import seminar.models as m
import seminar.views as v import seminar.views as v
from seminar.utils import sync_skoly from seminar.utils import sync_skoly
@tag('stejny-model-na-produkci')
class OrgSkolyAutocompleteTestCase(TestCase): class OrgSkolyAutocompleteTestCase(TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):

76
deploy_v2/admin_org_prava.json

@ -271,62 +271,62 @@
}, },
{ {
"codename": "add_konfera", "codename": "add_konfera",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "konfera" "ct_model": "konfera"
}, },
{ {
"codename": "change_konfera", "codename": "change_konfera",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "konfera" "ct_model": "konfera"
}, },
{ {
"codename": "delete_konfera", "codename": "delete_konfera",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "konfera" "ct_model": "konfera"
}, },
{ {
"codename": "view_konfera", "codename": "view_konfera",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "konfera" "ct_model": "konfera"
}, },
{ {
"codename": "add_konfery_ucastnici", "codename": "add_konfery_ucastnici",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "konfery_ucastnici" "ct_model": "konfery_ucastnici"
}, },
{ {
"codename": "change_konfery_ucastnici", "codename": "change_konfery_ucastnici",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "konfery_ucastnici" "ct_model": "konfery_ucastnici"
}, },
{ {
"codename": "delete_konfery_ucastnici", "codename": "delete_konfery_ucastnici",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "konfery_ucastnici" "ct_model": "konfery_ucastnici"
}, },
{ {
"codename": "view_konfery_ucastnici", "codename": "view_konfery_ucastnici",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "konfery_ucastnici" "ct_model": "konfery_ucastnici"
}, },
{ {
"codename": "add_nastaveni", "codename": "add_nastaveni",
"ct_app_label": "seminar", "ct_app_label": "various",
"ct_model": "nastaveni" "ct_model": "nastaveni"
}, },
{ {
"codename": "change_nastaveni", "codename": "change_nastaveni",
"ct_app_label": "seminar", "ct_app_label": "various",
"ct_model": "nastaveni" "ct_model": "nastaveni"
}, },
{ {
"codename": "delete_nastaveni", "codename": "delete_nastaveni",
"ct_app_label": "seminar", "ct_app_label": "various",
"ct_model": "nastaveni" "ct_model": "nastaveni"
}, },
{ {
"codename": "view_nastaveni", "codename": "view_nastaveni",
"ct_app_label": "seminar", "ct_app_label": "various",
"ct_model": "nastaveni" "ct_model": "nastaveni"
}, },
{ {
@ -351,22 +351,22 @@
}, },
{ {
"codename": "change_organizator", "codename": "change_organizator",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "organizator" "ct_model": "organizator"
}, },
{ {
"codename": "view_organizator", "codename": "view_organizator",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "organizator" "ct_model": "organizator"
}, },
{ {
"codename": "change_osoba", "codename": "change_osoba",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "osoba" "ct_model": "osoba"
}, },
{ {
"codename": "view_osoba", "codename": "view_osoba",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "osoba" "ct_model": "osoba"
}, },
{ {
@ -391,22 +391,22 @@
}, },
{ {
"codename": "add_prijemce", "codename": "add_prijemce",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "prijemce" "ct_model": "prijemce"
}, },
{ {
"codename": "change_prijemce", "codename": "change_prijemce",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "prijemce" "ct_model": "prijemce"
}, },
{ {
"codename": "delete_prijemce", "codename": "delete_prijemce",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "prijemce" "ct_model": "prijemce"
}, },
{ {
"codename": "view_prijemce", "codename": "view_prijemce",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "prijemce" "ct_model": "prijemce"
}, },
{ {
@ -431,12 +431,12 @@
}, },
{ {
"codename": "change_resitel", "codename": "change_resitel",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "resitel" "ct_model": "resitel"
}, },
{ {
"codename": "view_resitel", "codename": "view_resitel",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "resitel" "ct_model": "resitel"
}, },
{ {
@ -461,82 +461,82 @@
}, },
{ {
"codename": "add_skola", "codename": "add_skola",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "skola" "ct_model": "skola"
}, },
{ {
"codename": "change_skola", "codename": "change_skola",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "skola" "ct_model": "skola"
}, },
{ {
"codename": "delete_skola", "codename": "delete_skola",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "skola" "ct_model": "skola"
}, },
{ {
"codename": "view_skola", "codename": "view_skola",
"ct_app_label": "seminar", "ct_app_label": "personalni",
"ct_model": "skola" "ct_model": "skola"
}, },
{ {
"codename": "add_soustredeni", "codename": "add_soustredeni",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni" "ct_model": "soustredeni"
}, },
{ {
"codename": "change_soustredeni", "codename": "change_soustredeni",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni" "ct_model": "soustredeni"
}, },
{ {
"codename": "delete_soustredeni", "codename": "delete_soustredeni",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni" "ct_model": "soustredeni"
}, },
{ {
"codename": "view_soustredeni", "codename": "view_soustredeni",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni" "ct_model": "soustredeni"
}, },
{ {
"codename": "add_soustredeni_organizatori", "codename": "add_soustredeni_organizatori",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni_organizatori" "ct_model": "soustredeni_organizatori"
}, },
{ {
"codename": "change_soustredeni_organizatori", "codename": "change_soustredeni_organizatori",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni_organizatori" "ct_model": "soustredeni_organizatori"
}, },
{ {
"codename": "delete_soustredeni_organizatori", "codename": "delete_soustredeni_organizatori",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni_organizatori" "ct_model": "soustredeni_organizatori"
}, },
{ {
"codename": "view_soustredeni_organizatori", "codename": "view_soustredeni_organizatori",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni_organizatori" "ct_model": "soustredeni_organizatori"
}, },
{ {
"codename": "add_soustredeni_ucastnici", "codename": "add_soustredeni_ucastnici",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni_ucastnici" "ct_model": "soustredeni_ucastnici"
}, },
{ {
"codename": "change_soustredeni_ucastnici", "codename": "change_soustredeni_ucastnici",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni_ucastnici" "ct_model": "soustredeni_ucastnici"
}, },
{ {
"codename": "delete_soustredeni_ucastnici", "codename": "delete_soustredeni_ucastnici",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni_ucastnici" "ct_model": "soustredeni_ucastnici"
}, },
{ {
"codename": "view_soustredeni_ucastnici", "codename": "view_soustredeni_ucastnici",
"ct_app_label": "seminar", "ct_app_label": "soustredeni",
"ct_model": "soustredeni_ucastnici" "ct_model": "soustredeni_ucastnici"
}, },
{ {

13
galerie/migrations/0011_pre_split_soustredeni.py

@ -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

@ -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

@ -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 = [
]

2
galerie/models.py

@ -7,7 +7,7 @@ from imagekit.processors import ResizeToFit, Transpose
import os import os
from seminar.models import Soustredeni from soustredeni.models import Soustredeni
VZDY=0 VZDY=0
ORG=1 ORG=1

13
korektury/migrations/0021_auto_20240312_2124.py

@ -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 = [
]

30
korektury/migrations/0022_alter_komentar_autor_alter_korekturovanepdf_org_and_more.py

@ -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

@ -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 = [
]

2
korektury/models.py

@ -20,7 +20,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.text import get_valid_filename from django.utils.text import get_valid_filename
from seminar.models import Organizator from personalni.models import Organizator
import subprocess import subprocess
from reversion import revisions as reversion from reversion import revisions as reversion

13
personalni/migrations/0002_auto_20240312_2118.py

@ -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

@ -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,
},
),
]

34
personalni/migrations/0004_alter_organizator_options_alter_osoba_options_and_more.py

@ -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

@ -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

@ -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 = [
]

28
seminar/models/personalni.py → personalni/models.py

@ -12,7 +12,7 @@ from django_countries.fields import CountryField
from reversion import revisions as reversion from reversion import revisions as reversion
from .base import SeminarModelBase from seminar.models.base import SeminarModelBase
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -297,7 +297,7 @@ class Resitel(SeminarModelBase):
def vsechny_body(self): def vsechny_body(self):
"Spočítá body odjakživa." "Spočítá body odjakživa."
vsechna_reseni = self.reseni_set.all() vsechna_reseni = self.reseni_set.all()
from .odevzdavatko import Hodnoceni from seminar.models.odevzdavatko import Hodnoceni
vsechna_hodnoceni = Hodnoceni.objects.filter( vsechna_hodnoceni = Hodnoceni.objects.filter(
reseni__in=vsechna_reseni) reseni__in=vsechna_reseni)
return sum(h.body for h in list(vsechna_hodnoceni) if h.body is not None) 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 # - 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ů # - 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. # - 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()) 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) novejsi_hodnoceni = Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()).difference(hodnoceni_do_25_rocniku)
@ -382,7 +382,7 @@ class Resitel(SeminarModelBase):
else: else:
return Titul.akad 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()) 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( novejsi_body = body_z_hodnoceni(
Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()) Hodnoceni.objects.filter(reseni__in=self.reseni_set.all())
@ -411,6 +411,17 @@ class Resitel(SeminarModelBase):
@reversion.register(ignore_duplicates=True) @reversion.register(ignore_duplicates=True)
class Organizator(SeminarModelBase): 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', osoba = models.OneToOneField(Osoba, verbose_name='osoba', related_name='org',
help_text='osobní údaje organizátora', null=False, blank=False, help_text='osobní údaje organizátora', null=False, blank=False,
on_delete=models.PROTECT) on_delete=models.PROTECT)
@ -452,12 +463,3 @@ class Organizator(SeminarModelBase):
self.osoba.prijmeni) self.osoba.prijmeni)
else: else:
return "{} {}".format(self.osoba.jmeno, self.osoba.prijmeni) 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']

18
personalni/templates/personalni/profil/orgorozcestnik.html

@ -13,18 +13,18 @@
<li>soustředění</li> <li>soustředění</li>
</ul> </ul>
</li> </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> </ul>
<hr /> <hr />
<h2><strong>Tvorba čísla</strong></h2> <h2><strong>Tvorba čísla</strong></h2>
<ul> <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> <li><strong>korektury</strong>
<ul> <ul>
<li><a href="/korektury/">korekturování</a></li> <li><a href="{% url 'korektury_list' %}">korekturování</a></li>
<li><a href="/admin/korektury/korekturovanepdf/add/">přidat pdf k opravám</a></li> <li><a href="{% url 'admin:korektury_korekturovanepdf_add' %}">přidat pdf k opravám</a></li>
</ul> </ul>
</li> </li>
<li> <li>
@ -70,15 +70,15 @@
<h2><strong>Soustředění</strong></h2> <h2><strong>Soustředění</strong></h2>
<ul> <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> <li><strong>přednášky</strong>
<ul> <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> <li>hlasování o přednáškách</li>
</ul> </ul>
</li> </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> <ul>
<li>vytvoření galerie</li> <li>vytvoření galerie</li>
<li>stažení seznamu účastníků</li> <li>stažení seznamu účastníků</li>
@ -91,7 +91,7 @@
<h2><strong>Můj profil</strong></h2> <h2><strong>Můj profil</strong></h2>
<ul> <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> </ul>
<hr/> <hr/>
@ -108,6 +108,6 @@
</ul> </ul>
<hr /> <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 %} {% endblock content %}

13
prednasky/migrations/0013_auto_20240312_2124.py

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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 = [
]

3
prednasky/models.py

@ -2,7 +2,8 @@
from django.db import models 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_NAVRH = 1
STAV_BUDE = 2 STAV_BUDE = 2

17
seminar/migrations/0115_alter_nastaveni_options.py

@ -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

@ -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

@ -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 = [
]

33
seminar/migrations/0118_alter_organizator_options_alter_osoba_options_and_more.py

@ -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

@ -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'),
),
]

52
seminar/migrations/0120_remove_osoba_user_remove_prijemce_osoba_and_more.py

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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 = [
]

9
seminar/models/__init__.py

@ -1,8 +1,13 @@
from .tvorba import * from .tvorba import *
from .odevzdavatko import * from .odevzdavatko import *
from .base import * from .base import *
from .personalni import *
from .soustredeni import *
from .pomocne import * from .pomocne import *
from .treenode import * from .treenode import *
from .novinky 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
seminar/models/novinky.py

@ -4,7 +4,7 @@ from imagekit.processors import ResizeToFit
from reversion import revisions as reversion from reversion import revisions as reversion
from . import personalni as pm from personalni.models import Organizator
@reversion.register(ignore_duplicates=True) @reversion.register(ignore_duplicates=True)
class Novinky(models.Model): class Novinky(models.Model):
@ -26,7 +26,7 @@ class Novinky(models.Model):
], ],
options={'quality': 95}) 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) on_delete=models.SET_NULL)
zverejneno = models.BooleanField('Zveřejněno', default=False) zverejneno = models.BooleanField('Zveřejněno', default=False)

6
seminar/models/odevzdavatko.py

@ -10,11 +10,11 @@ from django.utils import timezone
from django.conf import settings from django.conf import settings
from seminar.models import tvorba as am 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 treenode as tm
from seminar.models import base as bm from seminar.models import base as bm
from seminar.utils import vzorecek_na_prepocet, inverze_vzorecku_na_prepocet from seminar.utils import vzorecek_na_prepocet, inverze_vzorecku_na_prepocet
from personalni.models import Resitel
@reversion.register(ignore_duplicates=True) @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', problem = models.ManyToManyField(am.Problem, verbose_name='problém', help_text='Problém',
through='Hodnoceni') 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') help_text='Seznam autorů řešení', through='Reseni_Resitele')
@ -229,7 +229,7 @@ class Reseni_Resitele(models.Model):
# Interní ID # Interní ID
id = models.AutoField(primary_key = True) 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) reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE)

4
seminar/models/treenode.py

@ -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 polymorphic.models import PolymorphicModel
from . import personalni as pm from personalni.models import Organizator
from .pomocne import Text from .pomocne import Text
@ -166,7 +166,7 @@ class OrgTextNode(TreeNode):
verbose_name = 'Organizátorský článek (Node)' verbose_name = 'Organizátorský článek (Node)'
verbose_name_plural = 'Organizátorské články (Node)' verbose_name_plural = 'Organizátorské články (Node)'
organizator = models.ForeignKey(pm.Organizator, organizator = models.ForeignKey(Organizator,
null=False, null=False,
blank=False, blank=False,
on_delete=models.DO_NOTHING, on_delete=models.DO_NOTHING,

43
seminar/models/tvorba.py

@ -34,7 +34,7 @@ from polymorphic.models import PolymorphicModel
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
from seminar.utils import aktivniResitele from seminar.utils import aktivniResitele
from . import personalni as pm from personalni.models import Prijemce, Organizator
from .base import SeminarModelBase from .base import SeminarModelBase
@ -306,7 +306,7 @@ class Cislo(SeminarModelBase):
resitele_vsichni.filter(zasilat_cislo_papirove=True)) 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." 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): def save(self, *args, **kwargs):
super().save(*args, **kwargs) super().save(*args, **kwargs)
@ -462,15 +462,15 @@ class Problem(SeminarModelBase,PolymorphicModel):
poznamka = models.TextField('org poznámky (HTML)', blank=True, 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 ...') 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, related_name='autor_problemu_%(class)s', null=True, blank=True,
on_delete=models.SET_NULL) 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, related_name='garant_problemu_%(class)s', null=True, blank=True,
on_delete=models.SET_NULL) 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') blank=True, related_name='opravovatele_%(class)s')
kod = models.CharField('lokální kód', max_length=32, blank=True, default='', 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) id = models.AutoField(primary_key=True)
autor = models.ForeignKey( autor = models.ForeignKey(
pm.Organizator, Organizator,
verbose_name="Autor pohádky", verbose_name="Autor pohádky",
# Při nahrávání z TeXu není vyplnění vyžadováno, v adminu je # 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: except ObjectDoesNotExist:
# Neexistující *Node nemá smysl aktualizovat. # Neexistující *Node nemá smysl aktualizovat.
pass 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

4
sifrovacka/admin.py

@ -1,8 +1,10 @@
from django.contrib import admin from django.contrib import admin
from .models import OdpovedUcastnika, SpravnaOdpoved from .models import OdpovedUcastnika, SpravnaOdpoved, NapovezenoUcastnikovi, Napoveda
# Register your models here. # Register your models here.
admin.site.register(OdpovedUcastnika) admin.site.register(OdpovedUcastnika)
admin.site.register(SpravnaOdpoved) admin.site.register(SpravnaOdpoved)
admin.site.register(Napoveda)
admin.site.register(NapovezenoUcastnikovi)

14
sifrovacka/forms.py

@ -1,6 +1,6 @@
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.forms import ModelForm, Textarea from django.forms import ModelForm, Textarea
from .models import OdpovedUcastnika, SpravnaOdpoved from .models import OdpovedUcastnika, SpravnaOdpoved, NapovezenoUcastnikovi, Napoveda
class SifrovackaForm(ModelForm): class SifrovackaForm(ModelForm):
@ -16,3 +16,15 @@ class SifrovackaForm(ModelForm):
if SpravnaOdpoved.objects.filter(sifra=sifra).count() == 0: if SpravnaOdpoved.objects.filter(sifra=sifra).count() == 0:
raise ValidationError("Tohle číslo šifry v databázi nemáme. Zkontrolujte si ho prosím.") raise ValidationError("Tohle číslo šifry v databázi nemáme. Zkontrolujte si ho prosím.")
return sifra 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

@ -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

@ -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

@ -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

@ -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 = [
]

19
sifrovacka/models.py

@ -1,7 +1,7 @@
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from seminar.models.personalni import Resitel from personalni.models import Resitel
# Create your models here. # Create your models here.
@ -25,3 +25,20 @@ class SpravnaOdpoved(models.Model):
def __str__(self): def __str__(self):
return f"{self.sifra}: {self.odpoved}" 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

@ -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

@ -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

@ -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 %}

4
sifrovacka/templates/sifrovacka/sifrovacka.html

@ -43,4 +43,8 @@
<input type="submit" value="Tak pravím!"> <input type="submit" value="Tak pravím!">
</form> </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 %} {% endblock content %}

17
sifrovacka/urls.py

@ -1,7 +1,7 @@
from django.urls import path from django.urls import path
from seminar.utils import org_required, resitel_or_org_required from seminar.utils import org_required, resitel_or_org_required
from .views import SifrovackaView, SifrovackaListView from .views import SifrovackaView, SifrovackaListView, NapovedaView, NapovedaListView, PreskoceniView
urlpatterns = [ urlpatterns = [
path( path(
@ -14,4 +14,19 @@ urlpatterns = [
org_required(SifrovackaListView.as_view()), org_required(SifrovackaListView.as_view()),
name='sifrovacka_odpovedi' 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'
),
] ]

43
sifrovacka/views.py

@ -2,9 +2,9 @@ from django.urls import reverse
from django.views.generic import FormView, ListView from django.views.generic import FormView, ListView
from seminar.views import formularOKView from seminar.views import formularOKView
from .forms import SifrovackaForm from .forms import SifrovackaForm, NapovedaForm
from .models import OdpovedUcastnika, SpravnaOdpoved from .models import OdpovedUcastnika, SpravnaOdpoved, Napoveda, NapovezenoUcastnikovi
from seminar.models.personalni import Resitel from personalni.models import Resitel
# Create your views here. # Create your views here.
@ -31,3 +31,40 @@ class SifrovackaView(FormView):
class SifrovackaListView(ListView): class SifrovackaListView(ListView):
template_name = 'sifrovacka/odpovedi_list.html' template_name = 'sifrovacka/odpovedi_list.html'
model = OdpovedUcastnika 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
soustredeni/admin.py

@ -2,7 +2,7 @@ from django.contrib import admin
from django.forms import widgets from django.forms import widgets
from django.db import models from django.db import models
from seminar.models import soustredeni as m import soustredeni.models as m
class SoustredeniUcastniciInline(admin.TabularInline): class SoustredeniUcastniciInline(admin.TabularInline):

122
soustredeni/migrations/0001_split_from_seminar.py

@ -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

@ -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

@ -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 = [
]

16
seminar/models/soustredeni.py → soustredeni/models.py

@ -8,9 +8,9 @@ from reversion import revisions as reversion
from django.conf import settings 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 from seminar.models import tvorba as am
logger = logging.getLogger(__name__) 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='', misto = models.CharField('místo soustředění', max_length=256, blank=True, default='',
help_text='Místo (název obce, volitelně též objektu') 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') 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í', verbose_name='Organizátoři soustředění',
help_text='Seznam organizátorů soustředění', help_text='Seznam organizátorů soustředění',
through='Soustredeni_Organizatori') through='Soustredeni_Organizatori')
@ -92,7 +92,7 @@ class Soustredeni_Ucastnici(SeminarModelBase):
# Interní ID # Interní ID
id = models.AutoField(primary_key = True) 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í', soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
on_delete=models.PROTECT) on_delete=models.PROTECT)
@ -118,7 +118,7 @@ class Soustredeni_Organizatori(SeminarModelBase):
# Interní ID # Interní ID
id = models.AutoField(primary_key = True) 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) on_delete=models.PROTECT)
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění', 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') help_text='Abstrakt konfery tak, jak byl uveden ve sborníku')
# FIXME: Umíme omezit jen na účastníky daného soustřeďka? # 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') help_text='Seznam účastníků konfery', through='Konfery_Ucastnici')
soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění', soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění',
@ -204,7 +204,7 @@ class Konfery_Ucastnici(models.Model):
# Interní ID # Interní ID
id = models.AutoField(primary_key = True) 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) konfera = models.ForeignKey(Konfera, verbose_name='konfera', on_delete=models.CASCADE)

52
split-apps-meta/create-ct-hack.py

@ -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

@ -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

@ -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

@ -0,0 +1,6 @@
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('APP', 'MIGR'),
]
operations = []

4
split-apps-meta/manage.notes

@ -0,0 +1,4 @@
1. smazat `managed = False`
2. makemigrations
Vazba na delete!
3. migrate

6
split-apps-meta/other

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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 = [
]

38
various/models.py

@ -1,3 +1,39 @@
from django.db import models 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

22
various/tests.py

@ -6,18 +6,18 @@ class MailTagsTest(TestCase):
"""Testuje template tagy ohledně mailů.""" """Testuje template tagy ohledně mailů."""
def test_maillink(self): 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. # 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.assertEqual(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.assertEqual(maillink('Hello', to=['some@body.test']), r'<a href="mailto:some@body.test">Hello</a>')
self.assertEquals( self.assertEqual(
maillink('Hello', to=['alice@test.test', 'bob@jinde.test']), maillink('Hello', to=['alice@test.test', 'bob@jinde.test']),
r'<a href="mailto:alice@test.test,bob@jinde.test">Hello</a>', 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"'), maillink('Hello', to='some@body.test', attrs='class="trida" id="id"'),
r'<a href="mailto:some@body.test" class="trida" id="id">Hello</a>', 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) # 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"), 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>', 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 self.assertRaises(TypeError, lambda: maillink()) # Nemá text, takže to shodí python
def test_mailurl(self): def test_mailurl(self):
self.assertEquals(mailurl(to='some@body.test'), r'mailto:some@body.test') self.assertEqual(mailurl(to='some@body.test'), r'mailto:some@body.test')
self.assertEquals(mailurl(to=['some@body.test']), r'mailto:some@body.test') self.assertEqual(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.assertEqual(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', body='Tělo', subject='Předmět'), 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', 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…) # TODO: Vyzkoušet i víc adresátů. (Nepamatuji si z hlavy syntaxi…)
r'{% maillink "Text" to="alice@test.test" subject="Oprava řešení" %}' r'{% maillink "Text" to="alice@test.test" subject="Oprava řešení" %}'
) )
self.assertEquals( self.assertEqual(
render_template(template), render_template(template),
r'<a href="mailto:alice@test.test?subject=Oprava%20%C5%99e%C5%A1en%C3%AD">Text</a>', 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'{% load mail %}'
r'{% mailurl to="alice@test.test" subject="Čau Alice" %}' 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…
Cancel
Save