2010-06-14 13 views
5

के आसपास नोड्स को सफलतापूर्वक कैसे स्थानांतरित करें django-mptt मुझे अपने दिमाग से बाहर निकालने के लिए दृढ़ लगता है। मैं कुछ अपेक्षाकृत सरल करने की कोशिश कर रहा हूं: मैं एक नोड को हटाने जा रहा हूं, और नोड के बच्चों के साथ कुछ उचित करने की आवश्यकता है। अर्थात्, मैं उन्हें एक स्तर पर ले जाना चाहता हूं ताकि वे अपने वर्तमान माता-पिता के माता-पिता के बच्चे हों।django-mptt:

यही है, अगर पेड़ लगता है:

Root 
    | 
Grandpa 
    | 
Father 
| | 
C1 C2 

मैं पिता को नष्ट करने के लिए जा रहा हूँ, और C1 और C2 चाहते हैं दादाजी के बच्चों किया जाना है।

यहाँ कोड मैं का उपयोग कर रहा है:

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() 

तो मैं फोन चाहते हैं:

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

यह काम करता है - लगभग। बच्चों दादा के रूप में अपने माता-पिता की रिपोर्ट:

c1.parent == grandpa # True 

दादा अपने बच्चों

c1 in grandpa.children.all() # True 

बीच C1 और C2 में गिना जाता है हालांकि, रूट इन बच्चों परित्याग कर देता है।

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

c1 in root.get_descendants() # False 

मैं बच्चों को कैसे स्थानांतरित कर सकता हूं और उनकी जड़ दूषित नहीं होती है?

+1

आप सुनिश्चित करें कि "father.parent = कोई नहीं" एक नोड को हटाने के लिए सही तरीका है कर रहे हैं आप child.move_node (माता-पिता) के साथ child.parent = माता-पिता की जगह ले सकता? – mawimawi

+0

इस मामले में मैं वास्तव में नोड को हटा नहीं रहा हूं - मैं इसे संग्रहीत कर रहा हूं। मैं इसे पेड़ से हटाना चाहता हूं। हालांकि आपके पास एक अच्छा मुद्दा है, मैं वास्तव में यहां पेड़ से इसे हटा नहीं रहा हूं। – Parand

+0

माता-पिता को किसी को भी सेट करने जैसा लगता है और बचत वास्तव में एक पेड़ से एक नोड को हटाने का तरीका है (एमपीटीटी परीक्षण मामलों के अनुसार), ताकि यह सही लगे। – Parand

उत्तर

6

आंतरिक lft और rght मूल्य पहली बार बदलते हैं जब आप बच्चे को सहेजते हैं (यानी आपके reparent_children विधि की अंतिम पंक्ति)। save() उन उदाहरणों को अपडेट नहीं करता है जिन्हें आप आसपास झूठ बोल सकते हैं। मैं लगता एक सुरक्षित तरीका यह करने के लिए हर बार डेटाबेस से उन्हें फिर से लाएं करने के लिए, इस तरह होगा:

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() 

मैं similar problems था एक समय पहले, और उस दृष्टिकोण मेरी समस्या हल।

+4

डोमिनिक से 'नोड मैनेजर' उत्तराधिकारी होना उपयोगी है, मैं इस विधि पर समाप्त हुआ, और यह * काम करने लगता है, हालांकि django-mptt I end के साथ लगातार अपनी खुद की संवेदना पर सवाल उठाते हुए।मुझे नहीं पता कि मैंने वास्तव में इस मुद्दे को ठीक किया है या इसे कहीं और छुपाया है या नहीं। – Parand

1

इस पुस्तकालय ने मुझे पिछले कुछ दिनों में वास्तव में भ्रमित कर दिया है - move_to वास्तव में ऐसा नहीं लगता है जो मैं चाहता हूं, और मेरा पेड़ सिंक हो रहा है। मैं एक समाधान के साथ आया कि मैं गति और nonontraditional-ness की कीमत पर, अधिक आत्मविश्वास में हूँ।

यह प्रबंधक विधि partial_rebuildhere के आसपास घूमता है।

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) 

यदि आप चाहें तो