2010-06-14 9 views
5

arasındaki düğümleri başarılı bir şekilde taşımak için django-mptt beni aklımdan çıkarmaya kararlı görünüyor. Göreceli olarak basit bir şey yapmaya çalışıyorum: Bir düğüm sileceğim ve düğümün çocukları ile mantıklı bir şeyler yapmam gerekecek. Yani, onları bir üst seviyeye taşımak istiyorum, o yüzden şimdiki ebeveynlerinin ebeveynlerinin çocukları. Babamı ben sileceğim ve dedem çocukları olmak C1 ve C2 istiyorumdjango-mptt:

Root 
    | 
Grandpa 
    | 
Father 
| | 
C1 C2 

: ağaç gibi görünüyorsa, bir

.

İşte kullanıyorum kodu:

class Node(models.Model): 
    first_name = models.CharField(max_length=80, blank=True) 
    parent  = models.ForeignKey('self', null=True, blank=True, related_name='children') 

    def reparent_children(self, parent): 
     print "Reparenting" 
     for child in self.get_children(): 
      print "Working on", child.first_name, "to parent", parent.email 
      parent = Node.objects.get(id=parent.id) 
      child.move_to(parent, 'last-child') 
      child.save() 

yüzden derim:

father.reparent_children(grandpa) 
father.parent = None 
father.save() 

Bu işleri - neredeyse. Çocukların Büyükbaba olarak ebeveynleri raporu:

c1.parent == grandpa # True 

Büyükbaba onun çocukları

c1 in grandpa.children.all() # True 

arasında C1 ve C2 sayar Ancak Kök bu çocukları reddetmedikçe.

c1.get_root() == father # c1's root is father, instead of Root 

c1 in root.get_descendants() # False 

Çocukları nasıl taşınır ve kökleri bozulmaz?

+1

isterseniz, child.move_node (ana) ile child.parent = veli yerini alabilir? – mawimawi

+0

Bu durumda, aslında düğümü silmiyorum - arşivliyorum. Onu ağaçtan çıkarmak istiyorum. İyi bir noktaya sahipsin, aslında onu buradan ağaçtan çıkartamıyorum. – Parand

+0

Ebeveynin Yok'a ayarlanmasını sağlar ve kaydetme aslında bir ağaçtan (mptt sınama durumlarına göre) bir düğümü kaldırmanın yoludur, bu yüzden doğru görünüyor. – Parand

cevap

6

İç lft ve rght değerleri, bir çocuğu ilk kez kaydettiğinizde (yani, reparent_children yönteminizin son satırı) değişecektir. save(), yalan söylediğin örnekleri güncellemiyor. Ben böyle, veritabanından her zaman onları tekrar getirin olacaktır Bunu yapmak için güvenli bir yol düşünmek :

def reparent_children(self, parent): print "Reparenting" for child in self.get_children(): print "Working on", child.first_name, "to parent", parent.email parent = Node.objects.get(id=parent.id) current_child = Node.objects.get(id = child.id) current_child.move_to(parent, 'last-child') current_child.save() 

Bir süre önce similar problems vardı ve bu yaklaşım benim sorun çözüldü. move_to gerçekten bunu yapmak istedikleri şeyleri görünmüyor ve benim ağaç senkronizasyon dışı yapmayı -

+4

Dominic, bu yöntemin en sona erdi 'dan devralan NodeManager' ve * görünüyor' yararlı olur sürekli kendi aklımı sorgulama.Sorunu gerçekten düzeltip düzeltmediğimi veya başka bir yere saklayıp saklamadığımı bilmiyorum. – Parand

1

Bu kütüphane gerçekten bu son birkaç gün kafamı karıştırmıştır. Hız ve alışılmamışlık pahasına daha güvendiğim bir çözüm buldum. partial_rebuildhere yönetici yöntemi etrafında döner.

def delete_node(self): 
    if not self.parent: 
     print("Should not delete root node, confusing behavior follows") 
     return 
    tree_id = self.tree_id 
    parent = self.parent 

    for child in self.get_children(): 
     child.parent = parent 
     child.save() 

    self.delete() 
    Node.objects.partial_rebuild(tree_id) 

siz "father.parent = Yok" bir düğüm silmek için doğru yol olduğuna eminiz size