Search code examples
pythondjangodjango-modelsdjango-viewsdjango-mptt

show category and sub-categories in hierarchy


I am using django-mptt for category model. I want to show a list of categories and sub-categories as in the screenshot. The way I could show is all the list without any structure like below

BEDROOM ITEMS

ALMIRAH

2 PIECE ALMIRAH

3 PIECE ALMIRAH

BED

DOUBLE SIZE LOW BED

QUEEN SIZE LOW BED

This way its hard to know which one is parent category and which one is child category and grand-child category etc. I could either show the above way or show only the parent category using Category.objects.root_nodes()

enter image description here

here is my model, views and template

class Category(MPTTModel):
    name = models.CharField(max_length=100, blank=True, null=True)
    image = models.ImageField(null=True, blank=True,
                              upload_to=upload_furniture_image_path)
    slug = models.SlugField(max_length=200, unique=True)
    parent = TreeForeignKey('self', null=True, blank=True,
                            related_name='children', db_index=True)


def furniture(request, slug):
    instance = get_object_or_404(Furniture, slug = slug)
    cart_obj, new_obj = Cart.objects.new_or_get(request)
    categories = Category.objects.all()
    context = {
        'furniture': instance,
        'cart': cart_obj,
        'categories': categories
    }
    return render(request, 'furnitures/furniture.html', context)




 <div class="panel-body">
      <ul class="nav nav-pills nav-stacked category-menu">
           {% for category in categories %}
              <li>{{category.name}}</li>
           {% endfor %}
       </ul>
  </div>

So my question is how could I separate Parent Category and child category so I can show as in screenshot?

Here is the parent category with its children and grand children

enter image description here


Solution

  • Since you are using MPTTModel, best solution is to use the mptt methods to traverse the tree.

    And if you want to display tree structure in templates, you might need to either write template tags/filters around mptt methods or use tags/filters provided by the mptt library.

    Example solution :

    views.py

    return render_to_response('furnitures/furniture.html',
                               {'nodes':Category.objects.all()}, 
                               context_instance=RequestContext(request))
    

    template:

    <ul class="root">
        {% recursetree nodes %}
            <li>
                {{ node.name }}
                {% if not node.is_leaf_node %}
                    <ul class="children">
                        {{ children }}
                    </ul>
    
                   {% endif %}
                </li>
            {% endrecursetree %}
        </ul>
    

    it is explained in detail here