Использование django-mptt, чтобы получить только те категории, которые имеют элементы

Пример структуры:

ALL UPPERCASE: Категория

Смешанный случай: пункт

ROOT ├── BOOKS │   ├── FICTION │   │   └── CLASSICS │   └── NON-FICTION ├── CLOTHING └── ELECTRONICS ├── LAPTOPS ├── PHONES │   ├── APPLE │   │   ├── iPhone 6 │   │   ├── iPhone 6 Plus │   │   ├── iPhone 6S │   │   └── iPhone 6S Plus │   ├── MOTOROLA │   │   ├── Moto G4 │   │   ├── Moto G4 Play │   │   ├── Moto G4 Plus │   │   └── Moto X │   └── SAMSUNG └── TABLETS └── APPLE

Я пытаюсь, чтобы на моей индексной странице отображалась только категория "ЭЛЕКТРОНИКА". Категория "ОДЕЖДА" не должна отображаться, поскольку она пуста, а категория "КНИГИ" также не должна отображаться, поскольку, хотя она имеет дочерние категории, у дочерних категорий нет элементов.

Аналогично, на странице "ЭЛЕКТРОНИКА" должна отображаться только категория "ТЕЛЕФОНЫ". Категория "LAPTOPS" не должна отображаться, поскольку она пуста, а категория "ТАБЛЕТКИ" также не должна отображаться, поскольку, хотя она имеет дочернюю категорию, в этой дочерней категории нет элементов.

Аналогично, на странице "ТЕЛЕФОНЫ" должны отображаться только категории "ЯБЛОКО" и "МОТОРОЛА", поскольку категория "SAMSUNG" пуста.

Что я пробовал для индексной страницы:

Category.objects.root_nodes().exclude(children__isnull=True)

Это успешно исключает категорию "ОДЕЖДА", но не исключает категорию "КНИГИ". Я понимаю, почему это не работает, но я не знаю, что делать вместо этого.

1 ответ

Решение

Я не думаю, что это возможно, используя только django-mptt методы и поля менеджера.

Вы могли бы придумать запрос, который фильтрует все категории с элементами (подумайте что-то вроде SELECT DISTINCT category_id FROM items), а затем выяснить набор корневых узлов этих категорий.

Плохая новость заключается в том, что, вероятно, ваш запрос не будет работать очень хорошо для описанного вами варианта использования, может быть, вы можете позволить себе иметь какое-нибудь денормализованное поле (например, подсчет элементов поддерева) или использовать поисковую систему, например elasticsearch для такого рода задач.

Другие вопросы по тегам