12

I want to use the JavaScript InfoVis Tooljit ( http://thejit.org ) to render a tree of mptt nodes in django. How can i create the required json structure (see http://thejit.org/static/v20/Jit/Examples/Spacetree/example1.code.html for an example) in django?

Thanks

sean2000
  • 506
  • 4
  • 12

6 Answers6

7

If you use the template functionality of django-mptt to generate the JSON data you should be able to do something like the following:

var json =    
{% recursetree nodes %}
{
    id: "{{ node.id }}",   
    name: "{{ node.name }}",   
    data: {},   
    children: [{{ children }}]
},
{% endrecursetree %}

The children tag is brilliant, basically calling recursetree for each child of the node. However there is a little messiness generated around commas with this solution as the mptt example is around list elements where such things aren't a problem.

A slightly larger bit of code solves this:

var json =    
{
    id: "{{ root.id }}",   
    name: "{{ root.name }}",   
    data: {},   
    children: [{% recursetree root.children %}
    {
        id: "{{ node.id }}",   
        name: "{{ node.name }}",   
        data: {},   
        children: [{{ children }}]
    }
    {% endrecursetree %}]
}

By making a distinction between the root node (presuming there is only one) which does not reside within an array but is instead assigned to a variable, compared to other nodes which live within the children of another node, the var x = y, issue is avoided.

There is still a problem with children: [x,y,z,] having a trailing comma. If that final comma is raising errors then in the view that has called the template you can always do a quick string replace to replace ,] with ]

Alternatively you could alter the {{ children }} call of mptt in some way to take a join string, but that would involve much more work.

Chris
  • 2,447
  • 1
  • 21
  • 27
  • I found a few issues with using this approach (adding commas between children nodes, and that all sub information didn't seem to enter correctly). It was very useful, however, to get me pointed in the right direction. – JayCrossler Jan 24 '15 at 21:11
2

If someone is looking for a solution based on templates with the recursetree tag, it is possible to use get_next_sibling to control commas. Adapting the example provided by Chris:

{% load mptt_tags %}
[
{% recursetree nodes %}
{
    "id": "{{ node.id }}",   
    "name": "{{ node.name }}",   
    "data": {},   
    "children": [{{ children }}]
}{% if node.get_next_sibling %},{% endif %}
{% endrecursetree %}
]
regiov
  • 41
  • 2
2

Create JSON without trailing comma problem:

{% full_tree_for_model YOUR_APP.YOUR_MODEL as nodes %}

var json =  {% for genre,structure in nodes|tree_info %}{% if structure.new_level %} [{ {% else %} },{ {% endif %}
id: "{{ genre.id }}",
children: {% if genre.is_leaf_node %}[]{% endif %}
{% for level in structure.closed_levels %}}]{% endfor %}{% endfor %}
0

If you want to write your own serializer or do this from a view you can do:

from mptt.templatetags.mptt_tags import cache_tree_children

queryset = Foo.objects.all().select_related('bar')
queryset = cache_tree_children(queryset)

Now the queryset is "cached", meaning you can use model API methods like get_children() without it hitting the database again.

dan-klasson
  • 13,734
  • 14
  • 63
  • 101
0

I found a great solution to rendering children with sub-data in this thread: fastest way to create JSON to reflect a tree structure in Python / Django using mptt (See the accepted answer by craigds). His method also caches results and uses the built in json.dumps to create the structure.

Community
  • 1
  • 1
JayCrossler
  • 2,079
  • 2
  • 22
  • 22
0

In Django view

from django.core import serializers
import json

json_str = serializers.serialize("json",Categories.objects.all())
json_data = json.loads(json_str)
Gaurav Nagar
  • 191
  • 2
  • 4