2

I am using django-mptt library for the category. I could show the list of categories in template but I wanted to indent it properly so user can know which is a main category and which one is sub-category and etc. The way i tried to structure is

{% recursetree nodes %}
  <li class="node">
    <a href="/category/{{ node.get_absolute_url }}"
      class="{% if not node.is_leaf_node and not node.is_root_node and node.is_child_node %} child_parent {% elif node.is_leaf_node and not node.is_root_node %}leaf_node{% endif %}">
      {{ node.name }}
      {% if node.is_root_node %}
        <span class="badge">{{ node.get_count_children }}</span>
      {% endif %}
    </a>
      {% if not node.is_leaf_node %}
          <ul class="children">
            <li>{{ children }}</li>
          </ul>
      {% endif %}
  </li>
{% endrecursetree %}

This yields the following design of category

enter image description here

Here Dressing Table is a child of Bedroom Items like Bed and Almirah not a child of Bed. How could i fix this? I know the problem is here

<a href="/category/{{ node.get_absolute_url }}"
class="{% if not node.is_leaf_node and not node.is_root_node and node.is_child_node %} child_parent {% elif node.is_leaf_node and not node.is_root_node %}leaf_node{% endif %}">

but could not fix this issue

Not the dressing table in the screenshot

enter image description here

Serenity
  • 3,884
  • 6
  • 44
  • 87
  • Do you mean `Dressing Table` is a `root` node? – joe Dec 05 '17 at 09:20
  • No, `dressing table` is a child of bedroom items (to quote) – Andrew Dec 05 '17 at 09:21
  • Then then render is correct already. `dressing table ` is a child of bedroom node. What is your expected structure? – joe Dec 05 '17 at 09:29
  • Its not me, but I'm guessing its supposed to be rendered like `Bed` and `Almirah`, again I quote from the line under the image. – Andrew Dec 05 '17 at 09:55
  • OK. I got the situation now. He needs to determine the leaf node. But that leaf node is the 2nd level from the root node. So he needs `Dressing Table` to be a `cyan` color. – joe Dec 05 '17 at 10:45
  • He needs a customized `tag` that make use method `get_children` or pass `get_children` that return `boolean` in the `context`. – joe Dec 05 '17 at 10:58
  • I have updated my question with the screenshot on how it should look like. – Serenity Dec 05 '17 at 11:17
  • @Sarit exactly. I want Dressing Table to be a cyan color with the same indentation level a bed and almirah has because its a child node(child node and also a leaf node because it has no children). – Serenity Dec 05 '17 at 11:21
  • @Serenity I am now following your question, but get this issue. If you know how to solve this. It will speed up me reaching your question. https://github.com/django-mptt/django-mptt/issues/614 – joe Dec 06 '17 at 04:52

1 Answers1

2

According to you updated answer.
Dinning Set, Kitchen Rack, and Kitchen Setup(Modular Kitchen) are supposed to be cyan since they are second level. If my understanding is correct.
Here is my hacked solution. If anybody found the better one please raise.

  1. Add extra method to the Model instance
  2. I have to add nodes to the context. (This would be an optional if you are using Django2.0 like mine)
  3. Use the instance method in the template

models.py

from django.db import models
from mptt.models import MPTTModel, TreeForeignKey


class Genre(MPTTModel):
    name = models.CharField(max_length=50, unique=True)
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True,
                            on_delete=models.CASCADE)

    class MPTTMeta:
        order_insertion_by = ['name']

    def __str__(self):
        return f'{self.name}'

    def is_second_node(self):
        return True if (self.get_ancestors().count() == 1) else False

views.py

from django.views.generic import ListView

from genres.models import Genre


class GenreListView(ListView):
    model = Genre
    template_name = 'genre_list.html'

    def get_context_data(self, *, object_list=None, **kwargs):
        """Get the context for this view."""
        queryset = object_list if object_list is not None else self.object_list
        page_size = self.get_paginate_by(queryset)
        context_object_name = self.get_context_object_name(queryset)
        if page_size:
            paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size)
            context = {
                'paginator': paginator,
                'page_obj': page,
                'is_paginated': is_paginated,
                'object_list': queryset
            }
        else:
            context = {
                'paginator': None,
                'page_obj': None,
                'is_paginated': False,
                'object_list': queryset
            }
        if context_object_name is not None:
            context[context_object_name] = queryset
        context.update(kwargs)
        context['nodes'] = context.get('object_list')
        return super().get_context_data(**context)

genre_list.html

<!DOCTYPE html>
{% load mptt_tags %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Genre ListView</title>
</head>
<style>
    .root {color: purple}
    .child{color: cyan}
    .leaf {color: gray}
</style>
<body>
    {% recursetree nodes %}
    <div class="
        {% if node.is_root_node %}
        root
        {% elif node.is_child_node and not node.is_leaf_node or node.is_second_node%}
        child
        {% elif node.is_leaf_node and not node.is_root_node%}
        leaf
        {%endif%}">
        {{node.name}}
        {{node.is_second_node}}
    </div>
    {% if not node.is_leaf_node%}
    <ul>{{children}}</ul>
    {% endif %}

    {% endrecursetree %}
</ul>
</body>
</html>

enter image description here

joe
  • 8,383
  • 13
  • 61
  • 109