Move treenode modely do vlastního souboru
This commit is contained in:
		
							parent
							
								
									babfd9c25d
								
							
						
					
					
						commit
						970352322c
					
				
					 4 changed files with 274 additions and 253 deletions
				
			
		|  | @ -4,3 +4,4 @@ from .base import * | ||||||
| from .personalni import * | from .personalni import * | ||||||
| from .soustredeni import * | from .soustredeni import * | ||||||
| from .pomocne import * | from .pomocne import * | ||||||
|  | from .treenode import * | ||||||
|  |  | ||||||
|  | @ -12,7 +12,6 @@ from django.conf import settings | ||||||
| from django.urls import reverse | from django.urls import reverse | ||||||
| from django.core.cache import cache | from django.core.cache import cache | ||||||
| from django.core.exceptions import ObjectDoesNotExist, ValidationError | from django.core.exceptions import ObjectDoesNotExist, ValidationError | ||||||
| from django.contrib.contenttypes.models import ContentType |  | ||||||
| from django.utils.text import get_valid_filename | from django.utils.text import get_valid_filename | ||||||
| from imagekit.models import ImageSpecField | from imagekit.models import ImageSpecField | ||||||
| from imagekit.processors import ResizeToFit | from imagekit.processors import ResizeToFit | ||||||
|  | @ -23,7 +22,7 @@ from taggit.managers import TaggableManager | ||||||
| 
 | 
 | ||||||
| from reversion import revisions as reversion | from reversion import revisions as reversion | ||||||
| 
 | 
 | ||||||
| from seminar.utils import roman, FirstTagParser # Pro získání úryvku z TextNode | from seminar.utils import roman | ||||||
| from seminar.utils import hlavni_problem | from seminar.utils import hlavni_problem | ||||||
| from treenode import treelib | from treenode import treelib | ||||||
| 
 | 
 | ||||||
|  | @ -37,7 +36,6 @@ from seminar.utils import aktivniResitele | ||||||
| from . import personalni as pm | from . import personalni as pm | ||||||
| 
 | 
 | ||||||
| from .base import SeminarModelBase | from .base import SeminarModelBase | ||||||
| from .pomocne import Text |  | ||||||
| 
 | 
 | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
| 
 | 
 | ||||||
|  | @ -304,6 +302,7 @@ class Cislo(SeminarModelBase): | ||||||
| 		except ObjectDoesNotExist: | 		except ObjectDoesNotExist: | ||||||
| 			# Neexistující *Node nemá smysl aktualizovat, ale je potřeba ho naopak vyrobit | 			# Neexistující *Node nemá smysl aktualizovat, ale je potřeba ho naopak vyrobit | ||||||
| 			logger.warning(f'Číslo {self} nemělo ČísloNode, vyrábím…') | 			logger.warning(f'Číslo {self} nemělo ČísloNode, vyrábím…') | ||||||
|  | 			from seminar.models.treenode import CisloNode | ||||||
| 			CisloNode.objects.create(cislo=self) | 			CisloNode.objects.create(cislo=self) | ||||||
| 
 | 
 | ||||||
| 	def clean(self): | 	def clean(self): | ||||||
|  | @ -480,6 +479,7 @@ class Tema(Problem): | ||||||
| 	def cislo_node(self): | 	def cislo_node(self): | ||||||
| 		tema_node_set = self.temavcislenode_set.all() | 		tema_node_set = self.temavcislenode_set.all() | ||||||
| 		tema_cisla_vyskyt = [] | 		tema_cisla_vyskyt = [] | ||||||
|  | 		from seminar.models.treenode import CisloNode | ||||||
| 		for tn in tema_node_set: | 		for tn in tema_node_set: | ||||||
| 			tema_cisla_vyskyt.append( | 			tema_cisla_vyskyt.append( | ||||||
| 				treelib.get_upper_node_of_type(tn, CisloNode).cislo) | 				treelib.get_upper_node_of_type(tn, CisloNode).cislo) | ||||||
|  | @ -558,6 +558,7 @@ class Uloha(Problem): | ||||||
| 
 | 
 | ||||||
| 	def cislo_node(self): | 	def cislo_node(self): | ||||||
| 		zadani_node = self.ulohazadaninode | 		zadani_node = self.ulohazadaninode | ||||||
|  | 		from seminar.models.treenode import CisloNode | ||||||
| 		return treelib.get_upper_node_of_type(zadani_node, CisloNode) | 		return treelib.get_upper_node_of_type(zadani_node, CisloNode) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -619,254 +620,6 @@ class Pohadka(SeminarModelBase): | ||||||
| 			pass | 			pass | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TreeNode(PolymorphicModel): |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = "seminar_nodes_treenode" |  | ||||||
| 		verbose_name = "TreeNode" |  | ||||||
| 		verbose_name_plural = "TreeNody" |  | ||||||
| 
 |  | ||||||
| 	# TODO: Nechceme radši jako root vyžadovat přímo RocnikNode? |  | ||||||
| 	root = models.ForeignKey('TreeNode', |  | ||||||
| 		related_name="potomci_set", |  | ||||||
| 		null = True, |  | ||||||
| 		blank = False, |  | ||||||
| 		on_delete = models.SET_NULL, # Vrcholy s null kořenem jsou sirotci bez ročníku  |  | ||||||
| 		verbose_name="kořen stromu") |  | ||||||
| 	first_child = models.OneToOneField('TreeNode', |  | ||||||
| 		related_name='father_of_first', |  | ||||||
| 		null = True, |  | ||||||
| 		blank = True, |  | ||||||
| 		on_delete=models.SET_NULL, |  | ||||||
| 		verbose_name="první potomek") |  | ||||||
| 	succ = models.OneToOneField('TreeNode', |  | ||||||
| 		related_name="prev", |  | ||||||
| 		null = True, |  | ||||||
| 		blank = True, |  | ||||||
| 		on_delete=models.SET_NULL, |  | ||||||
| 		verbose_name="další element na stejné úrovni") |  | ||||||
| 	nazev = models.TextField("název tohoto node", |  | ||||||
| 		help_text = "Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode", |  | ||||||
| 		blank=False,  |  | ||||||
| 		null=True) # Nezveřejnitelný název na stránky - pouze do adminu |  | ||||||
| 	zajimave = models.BooleanField(default = False, |  | ||||||
| 		verbose_name = "Zajímavé", |  | ||||||
| 		help_text = "Zobrazí se daná věc na rozcestníku témátek") |  | ||||||
| 	srolovatelne = models.BooleanField(null = True, blank = True, |  | ||||||
| 		verbose_name = "Srolovatelné", |  | ||||||
| 		help_text = "Bude na stránce témátka možnost tuto položku skrýt") |  | ||||||
| 
 |  | ||||||
| 	def getOdkazStr(self): # String na rozcestník |  | ||||||
| 		return self.first_child.getOdkazStr() |  | ||||||
| 
 |  | ||||||
| 	def getOdkaz(self): # ID HTML tagu, na který se bude scrollovat #{{self.getOdkaz}} |  | ||||||
| 	# Jsem si vědom, že tu potenciálně vznikají kolize. |  | ||||||
| 	# Přijdou mi natolik nepravděpodobné, že je neřeším |  | ||||||
| 	# Chtěl jsem ale hezké odkazy |  | ||||||
| 		string = unidecode(self.getOdkazStr()) |  | ||||||
| 		returnVal = "" |  | ||||||
| 		i = 0	 |  | ||||||
| 		while len(returnVal) < 16: # Max 15 znaků |  | ||||||
| 			if i == len(string): |  | ||||||
| 				break |  | ||||||
| 			if string[i] == " ": |  | ||||||
| 				returnVal += "-" |  | ||||||
| 			if string[i].isalnum(): |  | ||||||
| 				returnVal += string[i].lower() |  | ||||||
| 			i += 1 |  | ||||||
| 		return returnVal |  | ||||||
| 
 |  | ||||||
| 	def __str__(self): |  | ||||||
| 		if self.nazev: |  | ||||||
| 			return self.nazev |  | ||||||
| 		else: |  | ||||||
| 			#TODO: logování |  | ||||||
| 			return "Nepojmenovaný Treenode" |  | ||||||
| 	 |  | ||||||
| 	def save(self, *args, **kwargs): |  | ||||||
| 		self.aktualizuj_nazev() |  | ||||||
| 		super().save(*args, **kwargs) |  | ||||||
| 
 |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		raise NotImplementedError("Pokus o aktualizaci názvu obecného TreeNode místo konkrétní instance") |  | ||||||
| 
 |  | ||||||
| 	def get_admin_url(self): |  | ||||||
| 		content_type = ContentType.objects.get_for_model(self.__class__) |  | ||||||
| 		return reverse("admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,)) |  | ||||||
| 
 |  | ||||||
| class RocnikNode(TreeNode): |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = 'seminar_nodes_rocnik' |  | ||||||
| 		verbose_name = 'Ročník (Node)' |  | ||||||
| 		verbose_name_plural = 'Ročníky (Node)' |  | ||||||
| 	rocnik = models.OneToOneField(Rocnik, |  | ||||||
| 		on_delete = models.PROTECT, # Pokud chci mazat ročník, musím si Node pořešit ručně |  | ||||||
| 		verbose_name = "ročník") |  | ||||||
| 
 |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		self.nazev = "RocnikNode: "+str(self.rocnik) |  | ||||||
| 
 |  | ||||||
| class CisloNode(TreeNode): |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = 'seminar_nodes_cislo' |  | ||||||
| 		verbose_name = 'Číslo (Node)' |  | ||||||
| 		verbose_name_plural = 'Čísla (Node)' |  | ||||||
| 	cislo = models.OneToOneField(Cislo, |  | ||||||
| 		on_delete = models.PROTECT, # Pokud chci mazat číslo, musím si Node pořešit ručně |  | ||||||
| 		verbose_name = "číslo") |  | ||||||
| 
 |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		self.nazev = "CisloNode: "+str(self.cislo) |  | ||||||
| 
 |  | ||||||
| 	def getOdkazStr(self): |  | ||||||
| 		return "Číslo " + str(self.cislo) |  | ||||||
| 
 |  | ||||||
| class MezicisloNode(TreeNode): |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = 'seminar_nodes_mezicislo' |  | ||||||
| 		verbose_name = 'Mezičíslo (Node)' |  | ||||||
| 		verbose_name_plural = 'Mezičísla (Node)' |  | ||||||
| 
 |  | ||||||
| 	# TODO: Využít TreeLib |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		from treenode.treelib import safe_pred |  | ||||||
| 		if safe_pred(self) is not None: |  | ||||||
| 			if (self.prev.get_real_instance_class() != CisloNode and |  | ||||||
| 				self.prev.get_real_instance_class() != MezicisloNode): |  | ||||||
| 					raise ValueError("Předchůdce není číslo!") |  | ||||||
| 			posledni = self.prev.cislo |  | ||||||
| 			self.nazev = "MezicisloNode: Mezičíslo po čísle"+str(posledni) |  | ||||||
| 		elif self.root: |  | ||||||
| 			if self.root.get_real_instance_class() != RocnikNode: |  | ||||||
| 				raise ValueError("Kořen stromu není ročník!") |  | ||||||
| 			rocnik = self.root.rocnik |  | ||||||
| 			self.nazev = "MezicisloNode: První mezičíslo ročníku "+str(rocnik) |  | ||||||
| 		else: |  | ||||||
| 			print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") |  | ||||||
| 			self.nazev = "MezicisloNode: Neidentifikovatelné mezičíslo!" |  | ||||||
| 	def getOdkazStr(self): |  | ||||||
| 		return "Obsah dostupný pouze na webu" |  | ||||||
| 
 |  | ||||||
| class TemaVCisleNode(TreeNode): |  | ||||||
| 	""" Obsahuje příspěvky k tématu v daném čísle """ |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = 'seminar_nodes_temavcisle' |  | ||||||
| 		verbose_name = 'Téma v čísle (Node)' |  | ||||||
| 		verbose_name_plural = 'Témata v čísle (Node)' |  | ||||||
| 	tema = models.ForeignKey(Tema, |  | ||||||
| 		on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně |  | ||||||
| 		verbose_name = "téma v čísle") |  | ||||||
| 
 |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		self.nazev = "TemaVCisleNode: "+str(self.tema) |  | ||||||
| 
 |  | ||||||
| 	def getOdkazStr(self): |  | ||||||
| 		return str(self.tema) |  | ||||||
| 
 |  | ||||||
| class OrgTextNode(TreeNode): |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = 'seminar_nodes_orgtextnode' |  | ||||||
| 		verbose_name = 'Organizátorský článek (Node)' |  | ||||||
| 		verbose_name_plural = 'Organizátorské články (Node)' |  | ||||||
| 	 |  | ||||||
| 	organizator = models.ForeignKey(pm.Organizator, |  | ||||||
| 		null=False, |  | ||||||
| 		blank=False, |  | ||||||
| 		on_delete=models.DO_NOTHING, |  | ||||||
| 		verbose_name="Organizátor", |  | ||||||
| 		) |  | ||||||
| 	org_verejny = models.BooleanField(default = True, |  | ||||||
| 		verbose_name = "Org je veřejný?", |  | ||||||
| 		help_text = "Pokud ano, bude org pod článkem podepsaný", |  | ||||||
| 		null=False, |  | ||||||
| 		) |  | ||||||
| 
 |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		return f"OrgTextNode začínající následujícim: {self.first_child.nazev}" |  | ||||||
| 
 |  | ||||||
| 	# FIXME!!! |  | ||||||
| 	#def getOdkazStr(self): |  | ||||||
| 	#	return str(self.clanek) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class UlohaZadaniNode(TreeNode): |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = 'seminar_nodes_uloha_zadani' |  | ||||||
| 		verbose_name = 'Zadání úlohy (Node)' |  | ||||||
| 		verbose_name_plural = 'Zadání úloh (Node)' |  | ||||||
| 	uloha = models.OneToOneField(Uloha, |  | ||||||
| 		on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně |  | ||||||
| 		verbose_name = "úloha", |  | ||||||
| 		null=True, |  | ||||||
| 		blank=False) |  | ||||||
| 
 |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		self.nazev = "UlohaZadaniNode: "+str(self.uloha) |  | ||||||
| 
 |  | ||||||
| 	def getOdkazStr(self): |  | ||||||
| 		return str(self.uloha) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class PohadkaNode(TreeNode): |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = 'seminar_nodes_pohadka' |  | ||||||
| 		verbose_name = 'Pohádka (Node)' |  | ||||||
| 		verbose_name_plural = 'Pohádky (Node)' |  | ||||||
| 	pohadka = models.OneToOneField(Pohadka, |  | ||||||
| 		on_delete=models.PROTECT, # Pokud chci mazat pohádku, musím si Node pořešit ručně |  | ||||||
| 		verbose_name = "pohádka", |  | ||||||
| 		) |  | ||||||
| 
 |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		self.nazev = "PohadkaNode: "+str(self.pohadka) |  | ||||||
| 
 |  | ||||||
| class UlohaVzorakNode(TreeNode): |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = 'seminar_nodes_uloha_vzorak' |  | ||||||
| 		verbose_name = 'Vzorák úlohy (Node)' |  | ||||||
| 		verbose_name_plural = 'Vzoráky úloh (Node)' |  | ||||||
| 	uloha = models.OneToOneField(Uloha, |  | ||||||
| 		on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně |  | ||||||
| 		verbose_name = "úloha", |  | ||||||
| 		null=True, |  | ||||||
| 		blank=False) |  | ||||||
| 
 |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		self.nazev = "UlohaVzorakNode: "+str(self.uloha) |  | ||||||
| 
 |  | ||||||
| 	def getOdkazStr(self): |  | ||||||
| 		return str(self.uloha) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class TextNode(TreeNode): |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = 'seminar_nodes_obsah' |  | ||||||
| 		verbose_name = 'Text (Node)' |  | ||||||
| 		verbose_name_plural = 'Text (Node)' |  | ||||||
| 	text = models.ForeignKey(Text, |  | ||||||
| 		on_delete=models.CASCADE, |  | ||||||
| 		verbose_name = 'text') |  | ||||||
| 	 |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		self.nazev = "TextNode: "+str(self.text) |  | ||||||
| 
 |  | ||||||
| 	def getOdkazStr(self): |  | ||||||
| 		return str(self.text) |  | ||||||
| 
 |  | ||||||
| class CastNode(TreeNode): |  | ||||||
| 	class Meta: |  | ||||||
| 		db_table = 'seminar_nodes_cast' |  | ||||||
| 		verbose_name = 'Část (Node)' |  | ||||||
| 		verbose_name_plural = 'Části (Node)' |  | ||||||
| 	 |  | ||||||
| 	nadpis = models.CharField('Nadpis', max_length=100, help_text = 'Nadpis podvěšené části obsahu') |  | ||||||
| 
 |  | ||||||
| 	def aktualizuj_nazev(self): |  | ||||||
| 		self.nazev = "CastNode: "+str(self.nadpis) |  | ||||||
| 
 |  | ||||||
| 	def getOdkazStr(self): |  | ||||||
| 		return str(self.nadpis) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @reversion.register(ignore_duplicates=True) | @reversion.register(ignore_duplicates=True) | ||||||
| class Nastaveni(SingletonModel): | class Nastaveni(SingletonModel): | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ from django.conf import settings | ||||||
| 
 | 
 | ||||||
| from seminar.models import models_all as am | from seminar.models import models_all as am | ||||||
| from seminar.models import personalni as pm | from seminar.models import personalni as pm | ||||||
|  | from seminar.models import treenode as tm | ||||||
| from seminar.models.base import SeminarModelBase | from seminar.models.base import SeminarModelBase | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -173,7 +174,7 @@ class Reseni_Resitele(models.Model): | ||||||
|         return '{} od {}'.format(self.reseni, self.resitel) |         return '{} od {}'.format(self.reseni, self.resitel) | ||||||
|     # NOTE: Poteciální DB HOG bez select_related |     # NOTE: Poteciální DB HOG bez select_related | ||||||
| 
 | 
 | ||||||
| class ReseniNode(am.TreeNode): | class ReseniNode(tm.TreeNode): | ||||||
|     class Meta: |     class Meta: | ||||||
|         db_table = 'seminar_nodes_otistene_reseni' |         db_table = 'seminar_nodes_otistene_reseni' | ||||||
|         verbose_name = 'Otištěné řešení (Node)' |         verbose_name = 'Otištěné řešení (Node)' | ||||||
|  |  | ||||||
							
								
								
									
										266
									
								
								seminar/models/treenode.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								seminar/models/treenode.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,266 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | import logging | ||||||
|  | 
 | ||||||
|  | from django.db import models | ||||||
|  | from django.urls import reverse | ||||||
|  | from django.contrib.contenttypes.models import ContentType | ||||||
|  | 
 | ||||||
|  | from unidecode import unidecode # Používám pro získání ID odkazu (ještě je to někde po někom zakomentované) | ||||||
|  | 
 | ||||||
|  | from polymorphic.models import PolymorphicModel | ||||||
|  | 
 | ||||||
|  | from . import personalni as pm | ||||||
|  | 
 | ||||||
|  | from .pomocne import Text | ||||||
|  | 
 | ||||||
|  | logger = logging.getLogger(__name__) | ||||||
|  | 
 | ||||||
|  | from seminar.models import models_all as am | ||||||
|  | 
 | ||||||
|  | class TreeNode(PolymorphicModel): | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = "seminar_nodes_treenode" | ||||||
|  | 		verbose_name = "TreeNode" | ||||||
|  | 		verbose_name_plural = "TreeNody" | ||||||
|  | 
 | ||||||
|  | 	# TODO: Nechceme radši jako root vyžadovat přímo RocnikNode? | ||||||
|  | 	root = models.ForeignKey('TreeNode', | ||||||
|  | 		related_name="potomci_set", | ||||||
|  | 		null = True, | ||||||
|  | 		blank = False, | ||||||
|  | 		on_delete = models.SET_NULL, # Vrcholy s null kořenem jsou sirotci bez ročníku  | ||||||
|  | 		verbose_name="kořen stromu") | ||||||
|  | 	first_child = models.OneToOneField('TreeNode', | ||||||
|  | 		related_name='father_of_first', | ||||||
|  | 		null = True, | ||||||
|  | 		blank = True, | ||||||
|  | 		on_delete=models.SET_NULL, | ||||||
|  | 		verbose_name="první potomek") | ||||||
|  | 	succ = models.OneToOneField('TreeNode', | ||||||
|  | 		related_name="prev", | ||||||
|  | 		null = True, | ||||||
|  | 		blank = True, | ||||||
|  | 		on_delete=models.SET_NULL, | ||||||
|  | 		verbose_name="další element na stejné úrovni") | ||||||
|  | 	nazev = models.TextField("název tohoto node", | ||||||
|  | 		help_text = "Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode", | ||||||
|  | 		blank=False,  | ||||||
|  | 		null=True) # Nezveřejnitelný název na stránky - pouze do adminu | ||||||
|  | 	zajimave = models.BooleanField(default = False, | ||||||
|  | 		verbose_name = "Zajímavé", | ||||||
|  | 		help_text = "Zobrazí se daná věc na rozcestníku témátek") | ||||||
|  | 	srolovatelne = models.BooleanField(null = True, blank = True, | ||||||
|  | 		verbose_name = "Srolovatelné", | ||||||
|  | 		help_text = "Bude na stránce témátka možnost tuto položku skrýt") | ||||||
|  | 
 | ||||||
|  | 	def getOdkazStr(self): # String na rozcestník | ||||||
|  | 		return self.first_child.getOdkazStr() | ||||||
|  | 
 | ||||||
|  | 	def getOdkaz(self): # ID HTML tagu, na který se bude scrollovat #{{self.getOdkaz}} | ||||||
|  | 	# Jsem si vědom, že tu potenciálně vznikají kolize. | ||||||
|  | 	# Přijdou mi natolik nepravděpodobné, že je neřeším | ||||||
|  | 	# Chtěl jsem ale hezké odkazy | ||||||
|  | 		string = unidecode(self.getOdkazStr()) | ||||||
|  | 		returnVal = "" | ||||||
|  | 		i = 0	 | ||||||
|  | 		while len(returnVal) < 16: # Max 15 znaků | ||||||
|  | 			if i == len(string): | ||||||
|  | 				break | ||||||
|  | 			if string[i] == " ": | ||||||
|  | 				returnVal += "-" | ||||||
|  | 			if string[i].isalnum(): | ||||||
|  | 				returnVal += string[i].lower() | ||||||
|  | 			i += 1 | ||||||
|  | 		return returnVal | ||||||
|  | 
 | ||||||
|  | 	def __str__(self): | ||||||
|  | 		if self.nazev: | ||||||
|  | 			return self.nazev | ||||||
|  | 		else: | ||||||
|  | 			#TODO: logování | ||||||
|  | 			return "Nepojmenovaný Treenode" | ||||||
|  | 	 | ||||||
|  | 	def save(self, *args, **kwargs): | ||||||
|  | 		self.aktualizuj_nazev() | ||||||
|  | 		super().save(*args, **kwargs) | ||||||
|  | 
 | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		raise NotImplementedError("Pokus o aktualizaci názvu obecného TreeNode místo konkrétní instance") | ||||||
|  | 
 | ||||||
|  | 	def get_admin_url(self): | ||||||
|  | 		content_type = ContentType.objects.get_for_model(self.__class__) | ||||||
|  | 		return reverse("admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,)) | ||||||
|  | 
 | ||||||
|  | class RocnikNode(TreeNode): | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = 'seminar_nodes_rocnik' | ||||||
|  | 		verbose_name = 'Ročník (Node)' | ||||||
|  | 		verbose_name_plural = 'Ročníky (Node)' | ||||||
|  | 	rocnik = models.OneToOneField(am.Rocnik, | ||||||
|  | 		on_delete = models.PROTECT, # Pokud chci mazat ročník, musím si Node pořešit ručně | ||||||
|  | 		verbose_name = "ročník") | ||||||
|  | 
 | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		self.nazev = "RocnikNode: "+str(self.rocnik) | ||||||
|  | 
 | ||||||
|  | class CisloNode(TreeNode): | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = 'seminar_nodes_cislo' | ||||||
|  | 		verbose_name = 'Číslo (Node)' | ||||||
|  | 		verbose_name_plural = 'Čísla (Node)' | ||||||
|  | 	cislo = models.OneToOneField(am.Cislo, | ||||||
|  | 		on_delete = models.PROTECT, # Pokud chci mazat číslo, musím si Node pořešit ručně | ||||||
|  | 		verbose_name = "číslo") | ||||||
|  | 
 | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		self.nazev = "CisloNode: "+str(self.cislo) | ||||||
|  | 
 | ||||||
|  | 	def getOdkazStr(self): | ||||||
|  | 		return "Číslo " + str(self.cislo) | ||||||
|  | 
 | ||||||
|  | class MezicisloNode(TreeNode): | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = 'seminar_nodes_mezicislo' | ||||||
|  | 		verbose_name = 'Mezičíslo (Node)' | ||||||
|  | 		verbose_name_plural = 'Mezičísla (Node)' | ||||||
|  | 
 | ||||||
|  | 	# TODO: Využít TreeLib | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		from treenode.treelib import safe_pred | ||||||
|  | 		if safe_pred(self) is not None: | ||||||
|  | 			if (self.prev.get_real_instance_class() != CisloNode and | ||||||
|  | 				self.prev.get_real_instance_class() != MezicisloNode): | ||||||
|  | 					raise ValueError("Předchůdce není číslo!") | ||||||
|  | 			posledni = self.prev.cislo | ||||||
|  | 			self.nazev = "MezicisloNode: Mezičíslo po čísle"+str(posledni) | ||||||
|  | 		elif self.root: | ||||||
|  | 			if self.root.get_real_instance_class() != RocnikNode: | ||||||
|  | 				raise ValueError("Kořen stromu není ročník!") | ||||||
|  | 			rocnik = self.root.rocnik | ||||||
|  | 			self.nazev = "MezicisloNode: První mezičíslo ročníku "+str(rocnik) | ||||||
|  | 		else: | ||||||
|  | 			print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") | ||||||
|  | 			self.nazev = "MezicisloNode: Neidentifikovatelné mezičíslo!" | ||||||
|  | 	def getOdkazStr(self): | ||||||
|  | 		return "Obsah dostupný pouze na webu" | ||||||
|  | 
 | ||||||
|  | class TemaVCisleNode(TreeNode): | ||||||
|  | 	""" Obsahuje příspěvky k tématu v daném čísle """ | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = 'seminar_nodes_temavcisle' | ||||||
|  | 		verbose_name = 'Téma v čísle (Node)' | ||||||
|  | 		verbose_name_plural = 'Témata v čísle (Node)' | ||||||
|  | 	tema = models.ForeignKey(am.Tema, | ||||||
|  | 		on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně | ||||||
|  | 		verbose_name = "téma v čísle") | ||||||
|  | 
 | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		self.nazev = "TemaVCisleNode: "+str(self.tema) | ||||||
|  | 
 | ||||||
|  | 	def getOdkazStr(self): | ||||||
|  | 		return str(self.tema) | ||||||
|  | 
 | ||||||
|  | class OrgTextNode(TreeNode): | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = 'seminar_nodes_orgtextnode' | ||||||
|  | 		verbose_name = 'Organizátorský článek (Node)' | ||||||
|  | 		verbose_name_plural = 'Organizátorské články (Node)' | ||||||
|  | 	 | ||||||
|  | 	organizator = models.ForeignKey(pm.Organizator, | ||||||
|  | 		null=False, | ||||||
|  | 		blank=False, | ||||||
|  | 		on_delete=models.DO_NOTHING, | ||||||
|  | 		verbose_name="Organizátor", | ||||||
|  | 		) | ||||||
|  | 	org_verejny = models.BooleanField(default = True, | ||||||
|  | 		verbose_name = "Org je veřejný?", | ||||||
|  | 		help_text = "Pokud ano, bude org pod článkem podepsaný", | ||||||
|  | 		null=False, | ||||||
|  | 		) | ||||||
|  | 
 | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		return f"OrgTextNode začínající následujícim: {self.first_child.nazev}" | ||||||
|  | 
 | ||||||
|  | 	# FIXME!!! | ||||||
|  | 	#def getOdkazStr(self): | ||||||
|  | 	#	return str(self.clanek) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class UlohaZadaniNode(TreeNode): | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = 'seminar_nodes_uloha_zadani' | ||||||
|  | 		verbose_name = 'Zadání úlohy (Node)' | ||||||
|  | 		verbose_name_plural = 'Zadání úloh (Node)' | ||||||
|  | 	uloha = models.OneToOneField(am.Uloha, | ||||||
|  | 		on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně | ||||||
|  | 		verbose_name = "úloha", | ||||||
|  | 		null=True, | ||||||
|  | 		blank=False) | ||||||
|  | 
 | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		self.nazev = "UlohaZadaniNode: "+str(self.uloha) | ||||||
|  | 
 | ||||||
|  | 	def getOdkazStr(self): | ||||||
|  | 		return str(self.uloha) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class PohadkaNode(TreeNode): | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = 'seminar_nodes_pohadka' | ||||||
|  | 		verbose_name = 'Pohádka (Node)' | ||||||
|  | 		verbose_name_plural = 'Pohádky (Node)' | ||||||
|  | 	pohadka = models.OneToOneField(am.Pohadka, | ||||||
|  | 		on_delete=models.PROTECT, # Pokud chci mazat pohádku, musím si Node pořešit ručně | ||||||
|  | 		verbose_name = "pohádka", | ||||||
|  | 		) | ||||||
|  | 
 | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		self.nazev = "PohadkaNode: "+str(self.pohadka) | ||||||
|  | 
 | ||||||
|  | class UlohaVzorakNode(TreeNode): | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = 'seminar_nodes_uloha_vzorak' | ||||||
|  | 		verbose_name = 'Vzorák úlohy (Node)' | ||||||
|  | 		verbose_name_plural = 'Vzoráky úloh (Node)' | ||||||
|  | 	uloha = models.OneToOneField(am.Uloha, | ||||||
|  | 		on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně | ||||||
|  | 		verbose_name = "úloha", | ||||||
|  | 		null=True, | ||||||
|  | 		blank=False) | ||||||
|  | 
 | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		self.nazev = "UlohaVzorakNode: "+str(self.uloha) | ||||||
|  | 
 | ||||||
|  | 	def getOdkazStr(self): | ||||||
|  | 		return str(self.uloha) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TextNode(TreeNode): | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = 'seminar_nodes_obsah' | ||||||
|  | 		verbose_name = 'Text (Node)' | ||||||
|  | 		verbose_name_plural = 'Text (Node)' | ||||||
|  | 	text = models.ForeignKey(Text, | ||||||
|  | 		on_delete=models.CASCADE, | ||||||
|  | 		verbose_name = 'text') | ||||||
|  | 	 | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		self.nazev = "TextNode: "+str(self.text) | ||||||
|  | 
 | ||||||
|  | 	def getOdkazStr(self): | ||||||
|  | 		return str(self.text) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class CastNode(TreeNode): | ||||||
|  | 	class Meta: | ||||||
|  | 		db_table = 'seminar_nodes_cast' | ||||||
|  | 		verbose_name = 'Část (Node)' | ||||||
|  | 		verbose_name_plural = 'Části (Node)' | ||||||
|  | 	 | ||||||
|  | 	nadpis = models.CharField('Nadpis', max_length=100, help_text = 'Nadpis podvěšené části obsahu') | ||||||
|  | 
 | ||||||
|  | 	def aktualizuj_nazev(self): | ||||||
|  | 		self.nazev = "CastNode: "+str(self.nadpis) | ||||||
|  | 
 | ||||||
|  | 	def getOdkazStr(self): | ||||||
|  | 		return str(self.nadpis) | ||||||
		Loading…
	
		Reference in a new issue