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
This commit is contained in:
Tomas "Jethro" Pokorny 2020-05-30 23:54:09 +02:00
parent be7d587b82
commit 24642324ab
2 changed files with 63 additions and 32 deletions

View file

@ -27,6 +27,19 @@ def safe_pred(node):
except ObjectDoesNotExist:
return None
def safe_succ(node):
try:
return node.succ
except ObjectDoesNotExist:
return None
def safe_father_of_first(node):
first = first_brother(node)
try:
return first.father_of_first
except ObjectDoesNotExist:
return None
def first_brother(node):
if node is None:
return None
@ -35,14 +48,6 @@ def first_brother(node):
brother = safe_pred(brother)
return brother
# A to samé pro .father_of_first
def safe_father_of_first(node):
first = first_brother(node)
try:
return first.father_of_first
except ObjectDoesNotExist:
return None
## Rodinné vztahy
def get_parent(node):
# Nejdřív získáme prvního potomka...
@ -240,29 +245,9 @@ def swap(node, other):
class TreeLibError(RuntimeError):
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
#FIXME Neřeší father-of-first!
def swap_succ(node):
if node is None:
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:
pred.succ = None
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.save()
node.succ = post_succ
@ -283,6 +276,15 @@ def swap_succ(node):
pred.succ = succ
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
# Dokumentace viz wiki:
# (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()
# 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()

View file

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