Аннотация Django ORM с обходом дерева

Я использую библиотеку django-mptt для создания категорий для моего проекта. Модель довольно проста:

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

class Category(MPTTModel):
    name = models.CharField('Name', max_length=100, unique=True)
    color = models.CharField(
        'Color',
         max_length=100,
         blank=True,
         null=True
    )
    parent = TreeForeignKey(
        'self',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='children'
    )

    class MPTTMeta:
        order_insertion_by = ['name']

Цвет категории является необязательным и должен наследоваться от родителя, если он не определен. Так что просто для иллюстрации:

Main Category 1 (red) -> Subcategory 1
                      -> Subcategory 2 (blue)
                      -> Subcategory 3 (yellow) -> Subcategory 4

Подкатегория 4 не имеет определенного цвета и наследует цвет подкатегории 3 (желтый). Подкатегория 1 наследует цвет от основной категории 1 (синий) и т. Д.

На мой взгляд, у меня есть корневая категория, а затем построить дерево, используя get_descendants(include_self=True),
Как я могу аннотировать цвет для каждой категории <TreeQuerySet> ?

Для одной модели у меня есть следующий метод:

@property
def inherited_color(self):
    if self.color:
        return self.color
    return (self
            .get_ancestors(ascending=True, include_self=True)
            .filter(color__isnull=False)
            .values_list('color', flat=True)
            .first())

Но когда этот метод вызывается для списка категорий, это приводит к большому количеству запросов к базе данных!

Это пример из оболочки django:

>>> category
<Category: 3>
>>> category.color is None
True
>>> category.get_family().values_list('name', 'color')
<TreeQuerySet [('1', '#51DCFF'), ('2', None), ('3', None)]>
>>> category.inherited_color
'#51DCFF'

0 ответов

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