带有树遍历的Django ORM批注

时间:2018-12-27 09:45:18

标签: django django-mptt

我正在使用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 shell的示例:

>>> 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 个答案:

没有答案