Odstřel modelu TreeNode #67
					 22 changed files with 804 additions and 100 deletions
				
			
		|  | @ -5,5 +5,4 @@ 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 | ||||
|  |  | |||
							
								
								
									
										13
									
								
								odevzdavatko/migrations/0007_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								odevzdavatko/migrations/0007_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # 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 = [ | ||||
|     ] | ||||
							
								
								
									
										20
									
								
								odevzdavatko/migrations/0008_odstrel_treenode_relink.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								odevzdavatko/migrations/0008_odstrel_treenode_relink.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| # 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í'), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								odevzdavatko/migrations/0009_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								odevzdavatko/migrations/0009_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # 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 = [ | ||||
|     ] | ||||
|  | @ -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('seminar.ReseniNode', verbose_name='Plná verze textu řešení', | ||||
| 	text_cely = models.OneToOneField('treenode.ReseniNode', verbose_name='Plná verze textu řešení', | ||||
| 									 blank=True, null=True, related_name="reseni_cely_set", | ||||
| 									 on_delete=models.PROTECT) | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										13
									
								
								personalni/migrations/0016_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								personalni/migrations/0016_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # 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 = [ | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								personalni/migrations/0017_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								personalni/migrations/0017_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # 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 = [ | ||||
|     ] | ||||
							
								
								
									
										17
									
								
								seminar/migrations/0140_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								seminar/migrations/0140_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| # 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 = [ | ||||
|     ] | ||||
							
								
								
									
										69
									
								
								seminar/migrations/0141_odstrel_treenode_unmanage.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								seminar/migrations/0141_odstrel_treenode_unmanage.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,69 @@ | |||
| # 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)'}, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										153
									
								
								seminar/migrations/0142_odstrel_treenode_delete.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								seminar/migrations/0142_odstrel_treenode_delete.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,153 @@ | |||
| # 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', | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								seminar/migrations/0143_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								seminar/migrations/0143_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # 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 = [ | ||||
|     ] | ||||
							
								
								
									
										43
									
								
								seminar/migrations/0144_post_odstrel_vseho.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								seminar/migrations/0144_post_odstrel_vseho.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| # 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 = [ | ||||
|     ] | ||||
|  | @ -1,8 +1,5 @@ | |||
| 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 | ||||
|  | @ -10,6 +7,7 @@ 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 | ||||
|  |  | |||
|  | @ -1,20 +0,0 @@ | |||
| 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) | ||||
| 
 | ||||
|  | @ -1,69 +0,0 @@ | |||
| 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 | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										231
									
								
								treenode/migrations/0001_odstrel_treenode_create.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								treenode/migrations/0001_odstrel_treenode_create.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,231 @@ | |||
| # 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), | ||||
|     ] | ||||
							
								
								
									
										70
									
								
								treenode/migrations/0002_odstrel_treenode_manage.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								treenode/migrations/0002_odstrel_treenode_manage.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | |||
| # 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)'}, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										13
									
								
								treenode/migrations/0003_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								treenode/migrations/0003_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # 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 = [ | ||||
|     ] | ||||
|  | @ -8,9 +8,10 @@ from unidecode import unidecode # Používám pro získání ID odkazu (ještě | |||
| 
 | ||||
| from polymorphic.models import PolymorphicModel | ||||
| 
 | ||||
| from personalni.models import Organizator | ||||
| from seminar.models import SeminarModelBase | ||||
| 
 | ||||
| from .pomocne import Text | ||||
| from personalni.models import Organizator | ||||
| from odevzdavatko.models import Reseni | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
|  | @ -233,6 +234,58 @@ 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: | ||||
|  | @ -249,7 +302,6 @@ class TextNode(TreeNode): | |||
| 	def getOdkazStr(self): | ||||
| 		return str(self.text) | ||||
| 
 | ||||
| 
 | ||||
| class CastNode(TreeNode): | ||||
| 	class Meta: | ||||
| 		db_table = 'seminar_nodes_cast' | ||||
|  | @ -263,3 +315,36 @@ 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 | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										13
									
								
								tvorba/migrations/0004_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tvorba/migrations/0004_odstrel_treenode_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # 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 = [ | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								tvorba/migrations/0005_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								tvorba/migrations/0005_odstrel_treenode_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # 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 = [ | ||||
|     ] | ||||
|  | @ -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 seminar.models.treenode import CisloNode | ||||
| 			from treenode.models 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 seminar.models.treenode import CisloNode | ||||
| 		from treenode.models 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 seminar.models.treenode import CisloNode | ||||
| 		from treenode.models import CisloNode | ||||
| 		return treelib.get_upper_node_of_type(zadani_node, CisloNode) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue