Compare commits

..

No commits in common. "b606f031915d2ad0a90dc4a386b7e0b5da112e41" and "5c7710ed3afb902dca0ceb9f00e2faec565ebdec" have entirely different histories.

22 changed files with 100 additions and 804 deletions

View file

@ -5,4 +5,5 @@ set -exuo pipefail
ensure_web_installed
./manage.py graph_models seminar | dot -Tpdf > schema_seminar.pdf
./manage.py graph_models -a -g | dot -Tpdf > schema_all.pdf

View file

@ -1,13 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 19:45
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('odevzdavatko', '0006_tvorba_post'),
]
operations = [
]

View file

@ -1,20 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 20:44
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('treenode', '0001_odstrel_treenode_create'),
('odevzdavatko', '0007_odstrel_treenode_pre'),
]
operations = [
migrations.AlterField(
model_name='reseni',
name='text_cely',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='treenode.reseninode', verbose_name='Plná verze textu řešení'),
),
]

View file

@ -1,14 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 20:52
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('odevzdavatko', '0008_odstrel_treenode_relink'),
('treenode', '0003_odstrel_treenode_post'),
]
operations = [
]

View file

@ -49,7 +49,7 @@ class Reseni(bm.SeminarModelBase):
forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False,
default=FORMA_EMAIL)
text_cely = models.OneToOneField('treenode.ReseniNode', verbose_name='Plná verze textu řešení',
text_cely = models.OneToOneField('seminar.ReseniNode', verbose_name='Plná verze textu řešení',
blank=True, null=True, related_name="reseni_cely_set",
on_delete=models.PROTECT)

View file

@ -1,13 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 19:45
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('personalni', '0015_tvorba_post'),
]
operations = [
]

View file

@ -1,14 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 20:52
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('personalni', '0016_odstrel_treenode_pre'),
('treenode', '0003_odstrel_treenode_post'),
]
operations = [
]

View file

@ -1,17 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 19:45
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('seminar', '0139_tvorba_post'),
('odevzdavatko', '0007_odstrel_treenode_pre'),
('personalni', '0016_odstrel_treenode_pre'),
('tvorba', '0004_odstrel_treenode_pre'),
('contenttypes', '0002_remove_content_type_name'),
]
operations = [
]

View file

@ -1,69 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 19:56
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('seminar', '0140_odstrel_treenode_pre'),
]
operations = [
migrations.AlterModelOptions(
name='castnode',
options={'managed': False, 'verbose_name': 'Část (Node)', 'verbose_name_plural': 'Části (Node)'},
),
migrations.AlterModelOptions(
name='cislonode',
options={'managed': False, 'verbose_name': 'Číslo (Node)', 'verbose_name_plural': 'Čísla (Node)'},
),
migrations.AlterModelOptions(
name='mezicislonode',
options={'managed': False, 'verbose_name': 'Mezičíslo (Node)', 'verbose_name_plural': 'Mezičísla (Node)'},
),
migrations.AlterModelOptions(
name='obrazek',
options={'managed': False, 'verbose_name': 'obrázek', 'verbose_name_plural': 'obrázky'},
),
migrations.AlterModelOptions(
name='orgtextnode',
options={'managed': False, 'verbose_name': 'Organizátorský článek (Node)', 'verbose_name_plural': 'Organizátorské články (Node)'},
),
migrations.AlterModelOptions(
name='pohadkanode',
options={'managed': False, 'verbose_name': 'Pohádka (Node)', 'verbose_name_plural': 'Pohádky (Node)'},
),
migrations.AlterModelOptions(
name='reseninode',
options={'managed': False, 'verbose_name': 'Otištěné řešení (Node)', 'verbose_name_plural': 'Otištěná řešení (Node)'},
),
migrations.AlterModelOptions(
name='rocniknode',
options={'managed': False, 'verbose_name': 'Ročník (Node)', 'verbose_name_plural': 'Ročníky (Node)'},
),
migrations.AlterModelOptions(
name='temavcislenode',
options={'managed': False, 'verbose_name': 'Téma v čísle (Node)', 'verbose_name_plural': 'Témata v čísle (Node)'},
),
migrations.AlterModelOptions(
name='text',
options={'managed': False, 'verbose_name': 'text', 'verbose_name_plural': 'texty'},
),
migrations.AlterModelOptions(
name='textnode',
options={'managed': False, 'verbose_name': 'Text (Node)', 'verbose_name_plural': 'Text (Node)'},
),
migrations.AlterModelOptions(
name='treenode',
options={'managed': False, 'verbose_name': 'TreeNode', 'verbose_name_plural': 'TreeNody'},
),
migrations.AlterModelOptions(
name='ulohavzoraknode',
options={'managed': False, 'verbose_name': 'Vzorák úlohy (Node)', 'verbose_name_plural': 'Vzoráky úloh (Node)'},
),
migrations.AlterModelOptions(
name='ulohazadaninode',
options={'managed': False, 'verbose_name': 'Zadání úlohy (Node)', 'verbose_name_plural': 'Zadání úloh (Node)'},
),
]

View file

@ -1,153 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 20:47
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('seminar', '0141_odstrel_treenode_unmanage'),
('odevzdavatko', '0008_odstrel_treenode_relink'),
('treenode', '0001_odstrel_treenode_create'),
]
operations = [
migrations.RemoveField(
model_name='cislonode',
name='cislo',
),
migrations.RemoveField(
model_name='cislonode',
name='treenode_ptr',
),
migrations.RemoveField(
model_name='mezicislonode',
name='treenode_ptr',
),
migrations.RemoveField(
model_name='obrazek',
name='text',
),
migrations.RemoveField(
model_name='orgtextnode',
name='organizator',
),
migrations.RemoveField(
model_name='orgtextnode',
name='treenode_ptr',
),
migrations.RemoveField(
model_name='pohadkanode',
name='pohadka',
),
migrations.RemoveField(
model_name='pohadkanode',
name='treenode_ptr',
),
migrations.RemoveField(
model_name='reseninode',
name='reseni',
),
migrations.RemoveField(
model_name='reseninode',
name='treenode_ptr',
),
migrations.RemoveField(
model_name='rocniknode',
name='rocnik',
),
migrations.RemoveField(
model_name='rocniknode',
name='treenode_ptr',
),
migrations.RemoveField(
model_name='temavcislenode',
name='tema',
),
migrations.RemoveField(
model_name='temavcislenode',
name='treenode_ptr',
),
migrations.RemoveField(
model_name='textnode',
name='text',
),
migrations.RemoveField(
model_name='textnode',
name='treenode_ptr',
),
migrations.RemoveField(
model_name='treenode',
name='first_child',
),
migrations.RemoveField(
model_name='treenode',
name='polymorphic_ctype',
),
migrations.RemoveField(
model_name='treenode',
name='root',
),
migrations.RemoveField(
model_name='treenode',
name='succ',
),
migrations.RemoveField(
model_name='ulohavzoraknode',
name='treenode_ptr',
),
migrations.RemoveField(
model_name='ulohavzoraknode',
name='uloha',
),
migrations.RemoveField(
model_name='ulohazadaninode',
name='treenode_ptr',
),
migrations.RemoveField(
model_name='ulohazadaninode',
name='uloha',
),
migrations.DeleteModel(
name='CastNode',
),
migrations.DeleteModel(
name='CisloNode',
),
migrations.DeleteModel(
name='MezicisloNode',
),
migrations.DeleteModel(
name='Obrazek',
),
migrations.DeleteModel(
name='OrgTextNode',
),
migrations.DeleteModel(
name='PohadkaNode',
),
migrations.DeleteModel(
name='ReseniNode',
),
migrations.DeleteModel(
name='RocnikNode',
),
migrations.DeleteModel(
name='TemaVCisleNode',
),
migrations.DeleteModel(
name='Text',
),
migrations.DeleteModel(
name='TextNode',
),
migrations.DeleteModel(
name='TreeNode',
),
migrations.DeleteModel(
name='UlohaVzorakNode',
),
migrations.DeleteModel(
name='UlohaZadaniNode',
),
]

View file

@ -1,14 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 20:52
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('seminar', '0142_odstrel_treenode_delete'),
('treenode', '0003_odstrel_treenode_post'),
]
operations = [
]

View file

@ -1,43 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-03 01:55
from django.db import migrations
# Myšlenka: Tahle migrace o sobě prohlašuje, že závisí na všem, co se do téhle chvíle stalo. To má dva důsledky:
# 1. V okamžiku, kdy tahle migrace proběhne, tak už máme model ve stavu který očekáváme. IOW slouží jako bariéra, za kterou nemůžou přetéct úpravy ostatních aplikací (hlavně těch našich)
# 2. Zároveň ale tvrdíme, že k tomu, aby tahle migrace proběhla, potřebujeme (potenciálně relativně staré) verze cizích aplikací, což způsobí uspořádání opačným směrem: DB změny cizích aplikací naopak proběhnou až po této migraci
# Vzhledem k tomu, že by i naše předchozí aplikace měly záviset na těchto změnách, tak tím efektivně vynucujeme zachování stavu pro ty mezilehlé migrace, které možná (chybou) nedokumentovaně spoléhají na to, jak vypadají cizí aplikace.
# Plán do budoucna: Jakmile tahle migrace proběhne na všech myslitelných databázích, můžeme její předchůdce prostě smazat a nahradit nějakou výrazně snazší sadou migrací, která jen vygeneruje správně tabulky a závislosti podle aktuálního modelu.
# - To se ve skutečnosti vesměs už stalo, v odstřelených aplikacích jsou modely stejně všechny „nové s daty spadlými z nebe“. Je moc pozdě v noci, ale myslím si, že prostě bude stačit smazat závislosti na migracích v `seminar`i a celou aplikaci `seminar` zrušit. (Největší problém je to při nasazování DB z nuly např. u generování testdat…)
# Je otázka, jestli tahle migrace nemá bydlet ve `various` či jinde, aby se dala smazat celá složka `seminar`.
class Migration(migrations.Migration):
dependencies = [
('admin', '0003_logentry_add_action_flag_choices'),
('auth', '0012_alter_user_first_name_max_length'),
('authtoken', '0004_alter_tokenproxy_options'),
('contenttypes', '0002_remove_content_type_name'),
('flatpages', '0001_initial'),
('galerie', '0013_post_split_soustredeni'),
('header_fotky', '0001_initial'),
('korektury', '0024_vic_orgu_k_pdf'),
('novinky', '0004_alter_novinky_id'),
('odevzdavatko', '0009_odstrel_treenode_post'),
('personalni', '0017_odstrel_treenode_post'),
('prednasky', '0018_post_split_soustredeni'),
('reversion', '0002_add_index_on_version_for_content_type_and_db'),
('seminar', '0143_odstrel_treenode_post'),
('sessions', '0001_initial'),
('sifrovacka', '0006_personalni_post_migrate'),
('sites', '0002_alter_domain_unique'),
('sitetree', '0002_alter_treeitem_parent_alter_treeitem_tree'),
('soustredeni', '0010_tvorba_post'),
('taggit', '0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx'),
('treenode', '0003_odstrel_treenode_post'),
('tvorba', '0005_odstrel_treenode_post'),
('various', '0006_tvorba_post'),
('vyroci', '0001_initial'),
]
operations = [
]

View file

@ -1,5 +1,8 @@
from .tvorba import *
from .odevzdavatko import *
from .base import *
from .pomocne import *
from .treenode import *
from various.models import Nastaveni
from personalni.models import Organizator, Resitel, Skola, Prijemce, Osoba
@ -7,7 +10,6 @@ from soustredeni.models import Soustredeni, Soustredeni_Ucastnici, Soustredeni_O
from novinky.models import Novinky
from odevzdavatko.models import Reseni, PrilohaReseni, Reseni_Resitele, Hodnoceni
from tvorba.models import ZmrazenaVysledkovka, Deadline, Cislo, Rocnik, Pohadka, Tema, Problem, Problemy_Opravovatele, Uloha, Clanek
from treenode.models import UlohaVzorakNode, UlohaZadaniNode, CisloNode, TemaVCisleNode, OrgTextNode, Obrazek, RocnikNode, PohadkaNode, TextNode, MezicisloNode, ReseniNode, CastNode, Text, TreeNode
# Kvůli migr. 0041
from soustredeni.models import generate_filename_konfera

View file

@ -0,0 +1,20 @@
from django.db import models
from seminar.models import treenode as tm
from odevzdavatko.models import Reseni
class ReseniNode(tm.TreeNode):
class Meta:
db_table = 'seminar_nodes_otistene_reseni'
verbose_name = 'Otištěné řešení (Node)'
verbose_name_plural = 'Otištěná řešení (Node)'
reseni = models.ForeignKey(Reseni,
on_delete=models.PROTECT,
verbose_name = 'reseni')
def aktualizuj_nazev(self):
self.nazev = "ReseniNode: "+str(self.reseni)
def getOdkazStr(self):
return str(self.reseni)

69
seminar/models/pomocne.py Normal file
View file

@ -0,0 +1,69 @@
import logging
import os
from django.db import models
from .base import SeminarModelBase
logger = logging.getLogger(__name__)
class Text(SeminarModelBase):
class Meta:
db_table = 'seminar_texty'
verbose_name = 'text'
verbose_name_plural = 'texty'
na_web = models.TextField(
'text na web', blank=True,
help_text='Text ke zveřejnění na webu')
do_cisla = models.TextField(
'text do čísla', blank=True,
help_text='Text ke zveřejnění v čísle')
# má OneToOneField s:
# Reseni (je u něj jako reseni_cele)
# obrázky mají návaznost opačným směrem (vazba z druhé strany)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
# *Node.save() aktualizuje název *Nodu.
for tn in self.textnode_set.all():
tn.save()
def __str__(self):
return str(self.na_web)[:20]
class Obrazek(SeminarModelBase):
class Meta:
db_table = 'seminar_obrazky'
verbose_name = 'obrázek'
verbose_name_plural = 'obrázky'
# Interní ID
id = models.AutoField(primary_key=True)
na_web = models.ImageField(
'obrázek na web', upload_to='obrazky/%Y/%m/%d/',
null=True, blank=True)
text = models.ForeignKey(
Text, verbose_name='text',
help_text='text, ve kterém se obrázek vyskytuje',
null=False, blank=False, on_delete=models.CASCADE)
do_cisla_barevny = models.FileField(
'barevný obrázek do čísla',
help_text='Barevná verze obrázku do čísla',
upload_to='obrazky/%Y/%m/%d/', blank=True, null=True)
do_cisla_cernobily = models.FileField(
'černobílý obrázek do čísla',
help_text='Černobílá verze obrázku do čísla',
upload_to='obrazky/%Y/%m/%d/', blank=True, null=True)
# TODO placement hint - chci ho tady / pred textem / za textem

View file

@ -8,10 +8,9 @@ from unidecode import unidecode # Používám pro získání ID odkazu (ještě
from polymorphic.models import PolymorphicModel
from seminar.models import SeminarModelBase
from personalni.models import Organizator
from odevzdavatko.models import Reseni
from .pomocne import Text
logger = logging.getLogger(__name__)
@ -234,58 +233,6 @@ class UlohaVzorakNode(TreeNode):
def getOdkazStr(self):
return str(self.uloha)
class ReseniNode(TreeNode):
class Meta:
db_table = 'seminar_nodes_otistene_reseni'
verbose_name = 'Otištěné řešení (Node)'
verbose_name_plural = 'Otištěná řešení (Node)'
reseni = models.ForeignKey(Reseni,
on_delete=models.PROTECT,
verbose_name = 'reseni')
def aktualizuj_nazev(self):
self.nazev = "ReseniNode: "+str(self.reseni)
def getOdkazStr(self):
return str(self.reseni)
# LEdoian: Můžu prostě odstřelit Text a Obrázek do aplikace `treenode`, kam podle mě
# stejně patří? (Myšlenka, proč by tam měly patřit: tak, jak teď jsou je stejně
# využívají jen TreeNody a žádné rozhraní k nim stejně není, takže aktuálně
# použít nejdou (jako zbytek TN) a jejich sémantika pro „společnou tvorbu čísla
# na web a PDF“ je ze stejné školy. A taky kvůli nemíchání pokud vbrzku bude
# potřeba nějaký podobný model, navrhuji ho udělat znovu a klidně úplně stejně,
# staré věci pak buď zůstanou skryté, nebo je datově namigrujeme taková
# migrace bude snadná.) Jidáš: jo, a napiš tam tyhle myšlenky do komentáře.
# (zhruba přepis diskuse ve web-dev, 2024-10-30.)
class Text(SeminarModelBase):
class Meta:
db_table = 'seminar_texty'
verbose_name = 'text'
verbose_name_plural = 'texty'
na_web = models.TextField(
'text na web', blank=True,
help_text='Text ke zveřejnění na webu')
do_cisla = models.TextField(
'text do čísla', blank=True,
help_text='Text ke zveřejnění v čísle')
# má OneToOneField s:
# Reseni (je u něj jako reseni_cele)
# obrázky mají návaznost opačným směrem (vazba z druhé strany)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
# *Node.save() aktualizuje název *Nodu.
for tn in self.textnode_set.all():
tn.save()
def __str__(self):
return str(self.na_web)[:20]
class TextNode(TreeNode):
class Meta:
@ -302,6 +249,7 @@ class TextNode(TreeNode):
def getOdkazStr(self):
return str(self.text)
class CastNode(TreeNode):
class Meta:
db_table = 'seminar_nodes_cast'
@ -315,36 +263,3 @@ class CastNode(TreeNode):
def getOdkazStr(self):
return str(self.nadpis)
class Obrazek(SeminarModelBase):
class Meta:
db_table = 'seminar_obrazky'
verbose_name = 'obrázek'
verbose_name_plural = 'obrázky'
# Interní ID
id = models.AutoField(primary_key=True)
na_web = models.ImageField(
'obrázek na web', upload_to='obrazky/%Y/%m/%d/',
null=True, blank=True)
text = models.ForeignKey(
Text, verbose_name='text',
help_text='text, ve kterém se obrázek vyskytuje',
null=False, blank=False, on_delete=models.CASCADE)
do_cisla_barevny = models.FileField(
'barevný obrázek do čísla',
help_text='Barevná verze obrázku do čísla',
upload_to='obrazky/%Y/%m/%d/', blank=True, null=True)
do_cisla_cernobily = models.FileField(
'černobílý obrázek do čísla',
help_text='Černobílá verze obrázku do čísla',
upload_to='obrazky/%Y/%m/%d/', blank=True, null=True)
# TODO placement hint - chci ho tady / pred textem / za textem

View file

@ -1,231 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 20:06
from django.db import migrations, models
import django.db.models.deletion
def nastav_nove_contenttypes(apps, schema_editor):
ContentType = apps.get_model('contenttypes', 'ContentType')
# Seznam níž ověřen tím, že se skutečně při téhle migraci tabulka `django_content_type` (lokální v SQLite) změní správně :-)
for m in ('ulohavzoraknode', 'ulohazadaninode', 'cislonode', 'temavcislenode', 'orgtextnode', 'obrazek', 'rocniknode', 'pohadkanode', 'textnode', 'mezicislonode', 'reseninode', 'castnode', 'text', 'treenode'):
ContentType.objects.filter(app_label='seminar', model=m).update(app_label='treenode')
def nastav_stare_contenttypes(apps, schema_editor):
ContentType = apps.get_model('contenttypes', 'ContentType')
for m in ('ulohavzoraknode', 'ulohazadaninode', 'cislonode', 'temavcislenode', 'orgtextnode', 'obrazek', 'rocniknode', 'pohadkanode', 'textnode', 'mezicislonode', 'reseninode', 'castnode', 'text', 'treenode'):
ContentType.objects.filter(app_label='treenode', model=m).update(app_label='seminar')
class Migration(migrations.Migration):
initial = True
dependencies = [
('seminar', '0141_odstrel_treenode_unmanage'),
]
operations = [
migrations.CreateModel(
name='Obrazek',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('na_web', models.ImageField(blank=True, null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='obrázek na web')),
('do_cisla_barevny', models.FileField(blank=True, help_text='Barevná verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='barevný obrázek do čísla')),
('do_cisla_cernobily', models.FileField(blank=True, help_text='Černobílá verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='černobílý obrázek do čísla')),
('text', models.ForeignKey(help_text='text, ve kterém se obrázek vyskytuje', on_delete=django.db.models.deletion.CASCADE, to='treenode.text', verbose_name='text')),
],
options={
'verbose_name': 'obrázek',
'verbose_name_plural': 'obrázky',
'db_table': 'seminar_obrazky',
'managed': False,
},
),
migrations.CreateModel(
name='Text',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('na_web', models.TextField(blank=True, help_text='Text ke zveřejnění na webu', verbose_name='text na web')),
('do_cisla', models.TextField(blank=True, help_text='Text ke zveřejnění v čísle', verbose_name='text do čísla')),
],
options={
'verbose_name': 'text',
'verbose_name_plural': 'texty',
'db_table': 'seminar_texty',
'managed': False,
},
),
migrations.CreateModel(
name='TreeNode',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nazev', models.TextField(help_text='Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode', null=True, verbose_name='název tohoto node')),
('zajimave', models.BooleanField(default=False, help_text='Zobrazí se daná věc na rozcestníku témátek', verbose_name='Zajímavé')),
('srolovatelne', models.BooleanField(blank=True, help_text='Bude na stránce témátka možnost tuto položku skrýt', null=True, verbose_name='Srolovatelné')),
('first_child', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='father_of_first', to='treenode.treenode', verbose_name='první potomek')),
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype')),
('root', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='potomci_set', to='treenode.treenode', verbose_name='kořen stromu')),
('succ', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prev', to='treenode.treenode', verbose_name='další element na stejné úrovni')),
],
options={
'verbose_name': 'TreeNode',
'verbose_name_plural': 'TreeNody',
'db_table': 'seminar_nodes_treenode',
'managed': False,
},
),
migrations.CreateModel(
name='CastNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
('nadpis', models.CharField(help_text='Nadpis podvěšené části obsahu', max_length=100, verbose_name='Nadpis')),
],
options={
'verbose_name': 'Část (Node)',
'verbose_name_plural': 'Části (Node)',
'db_table': 'seminar_nodes_cast',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.CreateModel(
name='CisloNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
('cislo', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='tvorba.cislo', verbose_name='číslo')),
],
options={
'verbose_name': 'Číslo (Node)',
'verbose_name_plural': 'Čísla (Node)',
'db_table': 'seminar_nodes_cislo',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.CreateModel(
name='MezicisloNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
],
options={
'verbose_name': 'Mezičíslo (Node)',
'verbose_name_plural': 'Mezičísla (Node)',
'db_table': 'seminar_nodes_mezicislo',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.CreateModel(
name='OrgTextNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
('org_verejny', models.BooleanField(default=True, help_text='Pokud ano, bude org pod článkem podepsaný', verbose_name='Org je veřejný?')),
('organizator', models.ForeignKey( on_delete=django.db.models.deletion.DO_NOTHING, to='personalni.organizator', verbose_name='Organizátor')),
],
options={
'verbose_name': 'Organizátorský článek (Node)',
'verbose_name_plural': 'Organizátorské články (Node)',
'db_table': 'seminar_nodes_orgtextnode',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.CreateModel(
name='PohadkaNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
('pohadka', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='tvorba.pohadka', verbose_name='pohádka')),
],
options={
'verbose_name': 'Pohádka (Node)',
'verbose_name_plural': 'Pohádky (Node)',
'db_table': 'seminar_nodes_pohadka',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.CreateModel(
name='ReseniNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
('reseni', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='odevzdavatko.reseni', verbose_name='reseni')),
],
options={
'verbose_name': 'Otištěné řešení (Node)',
'verbose_name_plural': 'Otištěná řešení (Node)',
'db_table': 'seminar_nodes_otistene_reseni',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.CreateModel(
name='RocnikNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
('rocnik', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='tvorba.rocnik', verbose_name='ročník')),
],
options={
'verbose_name': 'Ročník (Node)',
'verbose_name_plural': 'Ročníky (Node)',
'db_table': 'seminar_nodes_rocnik',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.CreateModel(
name='TemaVCisleNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
('tema', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tvorba.tema', verbose_name='téma v čísle')),
],
options={
'verbose_name': 'Téma v čísle (Node)',
'verbose_name_plural': 'Témata v čísle (Node)',
'db_table': 'seminar_nodes_temavcisle',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.CreateModel(
name='TextNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
('text', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='treenode.text', verbose_name='text')),
],
options={
'verbose_name': 'Text (Node)',
'verbose_name_plural': 'Text (Node)',
'db_table': 'seminar_nodes_obsah',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.CreateModel(
name='UlohaVzorakNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='tvorba.uloha', verbose_name='úloha')),
],
options={
'verbose_name': 'Vzorák úlohy (Node)',
'verbose_name_plural': 'Vzoráky úloh (Node)',
'db_table': 'seminar_nodes_uloha_vzorak',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.CreateModel(
name='UlohaZadaniNode',
fields=[
('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='treenode.treenode')),
('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='tvorba.uloha', verbose_name='úloha')),
],
options={
'verbose_name': 'Zadání úlohy (Node)',
'verbose_name_plural': 'Zadání úloh (Node)',
'db_table': 'seminar_nodes_uloha_zadani',
'managed': False,
},
bases=('treenode.treenode',),
),
migrations.RunPython(nastav_nove_contenttypes, nastav_stare_contenttypes),
]

View file

@ -1,70 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 20:50
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('treenode', '0001_odstrel_treenode_create'),
('seminar', '0142_odstrel_treenode_delete'),
]
operations = [
migrations.AlterModelOptions(
name='castnode',
options={'verbose_name': 'Část (Node)', 'verbose_name_plural': 'Části (Node)'},
),
migrations.AlterModelOptions(
name='cislonode',
options={'verbose_name': 'Číslo (Node)', 'verbose_name_plural': 'Čísla (Node)'},
),
migrations.AlterModelOptions(
name='mezicislonode',
options={'verbose_name': 'Mezičíslo (Node)', 'verbose_name_plural': 'Mezičísla (Node)'},
),
migrations.AlterModelOptions(
name='obrazek',
options={'verbose_name': 'obrázek', 'verbose_name_plural': 'obrázky'},
),
migrations.AlterModelOptions(
name='orgtextnode',
options={'verbose_name': 'Organizátorský článek (Node)', 'verbose_name_plural': 'Organizátorské články (Node)'},
),
migrations.AlterModelOptions(
name='pohadkanode',
options={'verbose_name': 'Pohádka (Node)', 'verbose_name_plural': 'Pohádky (Node)'},
),
migrations.AlterModelOptions(
name='reseninode',
options={'verbose_name': 'Otištěné řešení (Node)', 'verbose_name_plural': 'Otištěná řešení (Node)'},
),
migrations.AlterModelOptions(
name='rocniknode',
options={'verbose_name': 'Ročník (Node)', 'verbose_name_plural': 'Ročníky (Node)'},
),
migrations.AlterModelOptions(
name='temavcislenode',
options={'verbose_name': 'Téma v čísle (Node)', 'verbose_name_plural': 'Témata v čísle (Node)'},
),
migrations.AlterModelOptions(
name='text',
options={'verbose_name': 'text', 'verbose_name_plural': 'texty'},
),
migrations.AlterModelOptions(
name='textnode',
options={'verbose_name': 'Text (Node)', 'verbose_name_plural': 'Text (Node)'},
),
migrations.AlterModelOptions(
name='treenode',
options={'verbose_name': 'TreeNode', 'verbose_name_plural': 'TreeNody'},
),
migrations.AlterModelOptions(
name='ulohavzoraknode',
options={'verbose_name': 'Vzorák úlohy (Node)', 'verbose_name_plural': 'Vzoráky úloh (Node)'},
),
migrations.AlterModelOptions(
name='ulohazadaninode',
options={'verbose_name': 'Zadání úlohy (Node)', 'verbose_name_plural': 'Zadání úloh (Node)'},
),
]

View file

@ -1,13 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 20:52
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('treenode', '0002_odstrel_treenode_manage'),
]
operations = [
]

View file

@ -1,13 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 19:45
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('tvorba', '0003_tvorba_post'),
]
operations = [
]

View file

@ -1,14 +0,0 @@
# Generated by Django 4.2.16 on 2024-11-02 20:52
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('tvorba', '0004_odstrel_treenode_pre'),
('treenode', '0003_odstrel_treenode_post'),
]
operations = [
]

View file

@ -297,7 +297,7 @@ class Cislo(SeminarModelBase):
except ObjectDoesNotExist:
# Neexistující *Node nemá smysl aktualizovat, ale je potřeba ho naopak vyrobit
logger.warning(f'Číslo {self} nemělo ČísloNode, vyrábím…')
from treenode.models import CisloNode
from seminar.models.treenode import CisloNode
CisloNode.objects.create(cislo=self)
def zlomovy_deadline_pro_papirove_cislo(self):
@ -572,7 +572,7 @@ class Tema(Problem):
def cislo_node(self):
tema_node_set = self.temavcislenode_set.all()
tema_cisla_vyskyt = []
from treenode.models import CisloNode
from seminar.models.treenode import CisloNode
for tn in tema_node_set:
tema_cisla_vyskyt.append(
treelib.get_upper_node_of_type(tn, CisloNode).cislo)
@ -648,7 +648,7 @@ class Uloha(Problem):
def cislo_node(self):
zadani_node = self.ulohazadaninode
from treenode.models import CisloNode
from seminar.models.treenode import CisloNode
return treelib.get_upper_node_of_type(zadani_node, CisloNode)