Seite 1 von 1

Django: Render HTML Treeview aus DB

Verfasst: Freitag 9. Oktober 2009, 17:55
von jakobusrex
benötigt:

Natural Language Toolkit (nltk)
http://www.nltk.org/

datei: projects.models.tree.py

Code: Alles auswählen

class tree(models.Model):
    id_prev = models.IntegerField() #implizit FK=>tree.id
    text = models.CharField(max_length=50)

    class Meta:
        ordering = ('id_prev', )

    def __unicode__(self):
        return self.tag

sql zum testen:

Code: Alles auswählen

insert into tree (id_prev, text) values (0, 'root');
// bekommt id=1 => root, MUSS vorhanden sein!!!!!!!!!!! sonst krachts.

insert into tree (id_prev, text) values (1, 'node_1');
// bekommt id=2

insert into tree (id_prev, text) values (2, 'node_1_1');
// bekommt id=3

insert into tree (id_prev, text) values (3, 'node_1_1_1');
// bekommt id=4

insert into tree (id_prev, text) values (0, 'node_2');
// bekommt id=5

insert into tree (id_prev, text) values (0, 'node_3');
// bekommt id=6

insert into tree (id_prev, text) values (5, 'node_2_1');
// bekommt id=7
datei projects.tree.py

Code: Alles auswählen

from nltk.tree import ParentedTree
from projects.models import tree

def render_tree(tree_id):
    treedata = tree.objects.all()
    
    map = {}
    for node in treedata:
        if node.id_prev == 0: #root, deshalb implizit FK (s.o.)
            root_node = ParentedTree('<li id="%s_node_%s">%s' % (tree_id, node.id, node.text), [])
            parent = root_node.root
            map[node.id] = parent
            continue
        
        parent = map[node.id_prev]

        leaf = ParentedTree('<li id="%s_node_%s">%s' % (tree_id, node.id, node.text), [])
        parent.append(leaf)
        map[node.id] = leaf

    tree_string = root_node.pprint(margin=0, indent=0, nodesep='#').replace('\n', '')
    tree_string = tree_string.replace('#)', '</li>')
    tree_string = tree_string.replace('#', '<ul>')
    tree_string = tree_string.replace(')', '</ul></li>')
    tree_string = tree_string.replace('(', '')
    tree_string = '<ul id="%s" class="treeview-black">%s</ul>' % (tree_id, tree_string)

    return tree_string
fertig ist eine UL baumstruktur
hübsch machen mit jquery=>treeview:
jquery: http://jquery.com/
treeview: http://bassistance.de/jquery-plugins/jq ... -treeview/

javascript:

Code: Alles auswählen

$(document).ready(function() 
{
$('#mytree').treeview();
}
hoffe der code funzt soweit, habs strg+c - strg+v und ein bissl editiert...
tippfehler inclusive? dann postet eine korrigierte version :) :)

Verfasst: Freitag 9. Oktober 2009, 21:46
von jens
HTML im Code ist doof. Du kannst auch die Template engine dafür nutzten. Wie habe ich hier aufgeschrieben: http://www.jensdiemer.de/_command/118/blog/detail/70/

wohl wahr

Verfasst: Samstag 10. Oktober 2009, 11:51
von jakobusrex
das sieht besser aus, ja, ich probier das mal :)

edit:
könntest du vielleicht mal deinen python-code posten, der die nodes/subnodes daten erstellt? dann müsste das nicht nochmal erfunden werden...
danke :)

Re: wohl wahr

Verfasst: Montag 12. Oktober 2009, 09:33
von jens
jakobusrex hat geschrieben:könntest du vielleicht mal deinen python-code posten, der die nodes/subnodes daten erstellt? dann müsste das nicht nochmal erfunden werden...
Ist wahrscheinlich ein wenig speziell: http://trac.pylucid.net/browser/branche ... y?rev=2330

Verfasst: Montag 12. Oktober 2009, 13:13
von jakobusrex
gut, dass wir darüber geredet haben :!:
ich hab jetzt folgenden lösungsvorschlag:

tree.py

Code: Alles auswählen

class Node:
    def __init__(self, n, s):
        self.id = n
        self.title = s
        self.children = {}

def make_treedict(root = 0):
    
    treedata = annotation_tree.objects.select_related().all()
    
    root = {}
    parentmap = {}
    
    for element in treedata:
        nodeId, parentId, title = (element.id, element.id_prev, element.tag)
        
        if parentId == 0: #root
            root[nodeId] = Node(nodeId, title)
            parentmap[nodeId] = root[nodeId]
            continue
        
        parent_node = parentmap[parentId]
        parent_node.children[nodeId] = Node(nodeId, title)
        parentmap[nodeId] = parent_node.children[nodeId]
        
    return root
view.py

Code: Alles auswählen

def annotations_all(request):
    treedict = make_treedict()
    return render_to_response('annotations_main.html', {'nodes': treedict}, context_instance=RequestContext(request)))
und die rekursion und das html in den templates (siehe jens' post)
annotations_main.html

Code: Alles auswählen

			<ul>
			{% include 'annotations_tree_items.html' %}
			</ul>
annotations_tree_items.html

Code: Alles auswählen

{% for idx, node in nodes.items %}
    <li>
        {{ node.title }}
        {% with "annotations_tree_items.html" as filename %}
        {% with node.children as nodes %}
			{% if nodes %}
            <ul>
                {% include filename %}
            </ul>
            {% endif %}
        {% endwith %}
        {% endwith %}
    </li>
{% endfor %}

zufrieden ? :) :)

die klasse Node kann jetzt noch so angepasst werden, dass zusätzliche daten dort gespeichert und im template verwendet werden können

Verfasst: Montag 12. Oktober 2009, 13:38
von jens
In meinem Falle (PyLucid) brauche ich halt noch mehr Funktionen ;)

Bsp: Wenn eine Seite für den Aktuellen User nicht sichtbar ist, sollen auch alle Unterseiten davon ausgeblendet werden...

Außerdem hab ich in PyLucid v0.9 die Trennung zwischen Baum und Inhalt (weil der Sprachabhängig ist)...