Django MPTT: values で tree_id が SELECT されてしまう

仕様である

django-mptt の TreeQuerySet で values コールすると SQL に tree_id が追加されているのは、django-mptt がツリー構造を管理するために必要なカラムだからです²。tree_id は、同じツリーに属するノードに同じ値を持ちます²。例えば、以下のようなモデルがあるとします。

1
2
3
4
5
6
7
8
9
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey

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

    class MPTTMeta:
        order_insertion_by = ['name']

このとき、以下のように values をコールすると、SQL に tree_id が追加されます²。

1
categories = Category.objects.values('name')
1
SELECT "category"."name", "category"."tree_id" FROM "category" ORDER BY "category"."tree_id" ASC, "category"."lft" ASC

このようにして、django-mptt はツリー構造を効率的に扱うことができます²。

ソース: Bing との会話 2023/4/28

標準のQuerySetを明示的に使う

TreeQuerySetが使われなくなるので tree_id(など)が SELECT のフィールドに追加されない

1
2
3
from django.db.models import QuerySet

categories = QuerySet(Category).values('name')