arm-path
@arm-path

Django ORM, MPTT — Получения количества суммы количества потомков?

Добрый день!
Возникла такая проблема, что необходимо в категориях скрыть те категории, в которых нет блогов. Но при создании категории использую модель MPTT древовидную структуру. Проблема, что у категории предка не окажется записей блога, но у его потомков они будут, и необходимо в таком случае запись категории предка показывать. А если у него нет потомков, то скрывать, либо если у потомков нет записей блога, так же скрывать. То есть нужно что бы в каждом этапе узнать сумму блогов потомков и самой категории, если она окажется меньше нуля, то его не показывать, и применить такое правило ко всем потомкам. То есть хочу добиться того, что бы скрыть дерево, если в нем совсем нет записей блога, и нет записей блога в его потомках.
Прикрепляю код:
models.py
class BlogCategories(MPTTModel):
    title = models.CharField(max_length=18, unique=True)
    slug = models.SlugField(max_length=18, unique=True)
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')

class Blog(models.Model):
    general = 'Общее'
    CHOICES_SHORTCUTS = (
        ('general', general),
        ('about_site_updates', 'Об обновлениях сайта'),
        ('about_the_author', 'Об авторе')
    )
    title = models.CharField(max_length=150, unique=True)
    slug = models.SlugField(max_length=150, unique=True)
    category = TreeForeignKey('BlogCategories', on_delete=models.CASCADE)
    shortcuts = models.CharField(max_length=150, choices=CHOICES_SHORTCUTS, default=general)
    content = models.TextField(blank=True)
    created_at = models.DateField(auto_now_add=True)
    posted_by = models.BooleanField(default=True)


inclusion_tag or views
Import ...

register = template.Library()


@register.inclusion_tag('blog/include_blog/header_container_blog.html')
def get_blog_categories(active_category = None):
    category_list = BlogCategories.objects.annotate(cnt=Count('blog', filter=Q(blog__shortcuts='general', blog__posted_by=True)))
- ВСЕ ЧТО СМОГ СДЕЛАТЬ, НО НУЖНО В CNT ХРАНИТЬ ПРОСУММИРОВАННОЕ ЗНАЧЕНИЕ БЛОГОВ САМОЙ КАТЕГОРИИ НА КОЛИЧЕСТВО БЛОГОВ ЕГО ПОТОМКОВ, ЧТО БЫ В ДАЛЬНЕЙШЕМ ПРОСТО УБРАТЬ ТО ЧТО БУДЕТ МЕНЬШЕ 0. И КАЖДЫЙ ПОТОМОК ДОЛЖЕН ПОВТОРИТЬ ТАКИЕ ЖЕ МАНИПУЛЯЦИИ НО НЕ ЗАТРАГИВАЯ УЖЕ ПРЕДКА.

return {'category_list': category_list, 'active_category': active_category}

Template
{% load static%}
<nav class="header-blog">
    {% load mptt_tags %}
        <ul>
            {% recursetree category_list %}
            {% if node in active_category.get_ancestors or node == active_category %}
            <li><a class = 'header-blog-link header-blog-active-category' href="{{node.get_absolute_url}}">{% if node.level == 0 %}<i></i>{% endif %}{{ node.title }}</a>
            {% else %}
            <li><a class = 'header-blog-link' href="{{node.get_absolute_url}}">{% if node.level == 0 %}<i></i>{% endif %}{{ node.title }}
            
            {% comment %} 
            - {{node.cnt}} - 
            {%for child in node.get_children %}
                {{child.cnt}} 
            {% endfor %} 
            {% endcomment %}
        
            </a>
            {% endif %}
                {% if not node.is_leaf_node %}
                <ul>
                    {{ children }}
                </ul>
                {% endif %}
            </li>
            {% endrecursetree %}
        </ul>
</nav>


Пример того что хочу получить:
5f1801f6071f4134857314.png
Если в саморазвитии 0 - блогов, а в финансовой грамотности 3 блога, то категорию саморазвитие необходимо оставить.
Если в саморазвитии 0 - блогов и в финансовой грамотности 0 блогов, то ветку нужно исключить из показа пользователю, так как в ней нет смысла.
Если в саморазвитии 3 блога, а в финансовой грамотности 0 блогов, то убрать только финансовую грамотность.

Но в связи именно использования mptt категории-потомки по количеству и вложенности не имеют ограничений.
  • Вопрос задан
  • 299 просмотров
Пригласить эксперта
Ответы на вопрос 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Django
Седой и строгий
Так как модель Blog не включена в иерархию MPTT, задача неизбежно приведёт к проблеме N+1. Так что либо вести в категории счётчик публикаций, либо опускаться на уровень ниже и городить что-то подобное.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы