Browse Source

seminar | TreeNode - treelib, referer, mazani

- v Treelib opraveno prohazovani TreeNodu, uz upravuje  otce u prvniho
syna
- pridano mazani vrcholu, vrchol s podstromem nejde smazat (a nenencha
se)
- operace modifikujici tvar stromu nyni pouzivaji referer pro navrat na
puvodni adresu
export_seznamu_prednasek
parent
commit
24642324ab
  1. 85
      seminar/treelib.py
  2. 8
      seminar/views/views_all.py

85
seminar/treelib.py

@ -27,15 +27,12 @@ def safe_pred(node):
except ObjectDoesNotExist: except ObjectDoesNotExist:
return None return None
def first_brother(node): def safe_succ(node):
if node is None: try:
return node.succ
except ObjectDoesNotExist:
return None return None
brother = node
while safe_pred(brother) is not None:
brother = safe_pred(brother)
return brother
# A to samé pro .father_of_first
def safe_father_of_first(node): def safe_father_of_first(node):
first = first_brother(node) first = first_brother(node)
try: try:
@ -43,6 +40,14 @@ def safe_father_of_first(node):
except ObjectDoesNotExist: except ObjectDoesNotExist:
return None return None
def first_brother(node):
if node is None:
return None
brother = node
while safe_pred(brother) is not None:
brother = safe_pred(brother)
return brother
## Rodinné vztahy ## Rodinné vztahy
def get_parent(node): def get_parent(node):
# Nejdřív získáme prvního potomka... # Nejdřív získáme prvního potomka...
@ -240,29 +245,9 @@ def swap(node, other):
class TreeLibError(RuntimeError): class TreeLibError(RuntimeError):
pass pass
@transaction.atomic
def swap_pred(node):
if node is None:
raise TreeLibError("Nelze přesunout None. Tohle by se nemělo stát.")
pred = safe_pred(node)
if pred is None:
raise TreeLibError("Nelze posunout vlevo, není tam žádný další uzel.")
pre_pred = safe_pred(pred)
succ = node.succ
#TODO zkontrolovaz, ze toto poradi nerozbiji db a neskonci s unique constraint violation
if pre_pred is not None:
pre_pred.succ = None
pre_pred.save()
node.succ = pred
node.save()
pred.succ = succ
pred.save()
if pre_pred is not None:
pre_pred.succ = node
pre_pred.save()
@transaction.atomic @transaction.atomic
#FIXME Neřeší father-of-first!
def swap_succ(node): def swap_succ(node):
if node is None: if node is None:
raise TreeLibError("Nelze přesunout None. Tohle by se nemělo stát.") raise TreeLibError("Nelze přesunout None. Tohle by se nemělo stát.")
@ -275,6 +260,14 @@ def swap_succ(node):
if pred is not None: if pred is not None:
pred.succ = None pred.succ = None
pred.save() pred.save()
# Nemame predchudce -> je potreba upravit otce
father = safe_father_of_first(node)
if pred is None and father is not None: # Mame otce
father.first_child = succ
father.save()
succ.succ = node succ.succ = node
succ.save() succ.save()
node.succ = post_succ node.succ = post_succ
@ -283,6 +276,15 @@ def swap_succ(node):
pred.succ = succ pred.succ = succ
pred.save() pred.save()
@transaction.atomic
def swap_pred(node):
if node is None:
raise TreeLibError("Nelze přesunout None. Tohle by se nemělo stát.")
pred = safe_pred(node)
if pred is None:
raise TreeLibError("Nelze posunout vlevo, není tam žádný další uzel.")
return swap_succ(pred)
# Rotace stromu # Rotace stromu
# Dokumentace viz wiki: # Dokumentace viz wiki:
# (lower bude jednoduchá rotace, ne mega, existence jednoduché rotace mi došla až po nakreslení obrázku) # (lower bude jednoduchá rotace, ne mega, existence jednoduché rotace mi došla až po nakreslení obrázku)
@ -336,3 +338,30 @@ def lower_node(node):
subtree2_tail.save() subtree2_tail.save()
# To by mělo být všechno... # To by mělo být všechno...
def delete_node(node):
if node is None:
raise TreeLibError("Nelze smazat None. Tohle by se nemělo stát.")
if node.first_child:
raise TreeLibError("Mazání TreeNode s potomky není podporováno.")
print(f'My:{node}, predchudce:{safe_pred(node)}, naslednik:{safe_succ(node)}, otec:{safe_father_of_first(node)}')
# Jsme prvnim synem
if safe_pred(node) is None:
if safe_succ(node) is None: # Jsme jedinym synem - upravime otce (pokud mame) a smazeme se
father = safe_father_of_first(node)
if father is not None:
father.first_child = None
father.save()
node.delete()
return
else: # mame bratra
swap_succ(node) # Staneme se neprvním synem, pokracujeme mimo if
# Jsme neprvním synem
prev = node.prev
prev.succ = node.succ
node.delete()
prev.save()

8
seminar/views/views_all.py

@ -190,8 +190,9 @@ class TreeNodeSmazatView(generic.base.View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
node = s.TreeNode.objects.get(pk=self.kwargs['pk']) node = s.TreeNode.objects.get(pk=self.kwargs['pk'])
if node.first_child: if node.first_child:
raise NotImplemented('Mazání TreeNode se syny není zatím podporováno!') raise NotImplementedError('Mazání TreeNode se syny není zatím podporováno!')
node.delete() treelib.delete_node(node)
return redirect(request.headers.get('referer'))
class TreeNodeOdvesitView(generic.base.View): class TreeNodeOdvesitView(generic.base.View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
@ -206,12 +207,13 @@ class TreeNodePodvesitView(generic.base.View):
if kam == 'pred': if kam == 'pred':
lower_node(node) lower_node(node)
elif kam == 'za': elif kam == 'za':
raise NotImplemented('Podvěsit za není zatím podporováno') raise NotImplementedError('Podvěsit za není zatím podporováno')
class TreeNodeProhoditView(generic.base.View): class TreeNodeProhoditView(generic.base.View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
node = s.TreeNode.objects.get(pk=self.kwargs['pk']) node = s.TreeNode.objects.get(pk=self.kwargs['pk'])
treelib.swap_succ(node) treelib.swap_succ(node)
return redirect(request.headers.get('referer'))
#FIXME ve formulari predat puvodni url a vratit redirect na ni #FIXME ve formulari predat puvodni url a vratit redirect na ni

Loading…
Cancel
Save