django 一个表中包括id和parentid,如何通过parentid找到全部父爷id

在Django中,如果你想要通过parentid找到一个记录的所有祖先(父祖)记录的id,你可以通过递归查询来实现。在Django中,你可以使用Django的Treebeard库来处理树形结构的数据,例如MPTT(Modified Preorder Tree Traversal)。但是,如果你不想使用第三方库或者你的需求比较简单,你可以通过编写递归查询函数来实现。

这里有两种常见的方法来实现:

方法1:使用Django的QuerySet的annotate和Subquery

这种方法适用于Django 2.0及以上版本。

from django.db.models import Subquery, OuterRef, IntegerField

def get_all_ancestors_ids(instance):

首先找到所有祖先的id

ancestors_ids = YourModel.objects.filter(

id=OuterRef('parentid')

).values('id')

复制代码
# 通过Subquery获取所有祖先的id
all_ancestors_ids = YourModel.objects.filter(
    id=instance.id
).annotate(
    all_ancestors_ids=Subquery(
        ancestors_ids.values('id')[:'id'][:'id'][:'id'][:'id'][:'id'][:'id'][:'id'][:'id'][:'id'][:'id'][:'id'][:'id'][:'id'][:'id'][:'id'][:'id']  # 这里理论上应该有无限层级的递归查询,但实际上你需要根据实际层级来调整,例如最多10层
    )
).values_list('all_ancestors_ids', flat=True)

return list(all_ancestors_ids)

注意:这种方法理论上可以实现无限层级的递归查询,但实际上你需要手动指定层级数(例如上面代码中的层级数仅为示例,你需要根据实际情况调整)。这种方法在层级非常深的情况下可能不实用。

方法2:递归函数查询

对于简单的应用场景,你可以定义一个递归函数来手动查找所有祖先。

def get_all_ancestors(instance):

ancestors = \[\]

current = instance

while current.parentid is not None:

current = YourModel.objects.get(id=current.parentid)

ancestors.append(current.id)

return ancestors::-1 # 返回时反转列表以获得正确的顺序(从祖先到子孙)

使用这个函数,你可以像这样调用它:

instance = YourModel.objects.get(id=some_id)

ancestors = get_all_ancestors(instance)

print(ancestors)

方法3:使用MPTT库(推荐对于复杂树形结构)

如果你需要处理更复杂的树形结构(例如,需要频繁查询祖先节点等),建议使用MPTT库。首先安装MPTT:

pip install django-mptt

然后在你的模型中使用MPTT:

from mptt.models import MPTTModel, TreeForeignKey

from django.db import models

class Category(MPTTModel):

name = models.CharField(max_length=50)

parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')

复制代码
def get_ancestors(self, ascending=False, include_self=False):
    ancestors = self.get_cached_ancestors(ascending=ascending, include_self=include_self)
    return [a.id for a in ancestors]  # 获取所有祖先的ID列表

使用:

instance = Category.objects.get(id=some_id)

ancestors_ids = instance.get_ancestors(include_self=False) # 获取所有父祖ID,不包括自身

print(ancestors_ids)

MPTT提供了非常强大的树形结构操作能力,包括但不限于获取祖先、子孙等。如果你预计会有很多复杂的树形操作需求,使用MPTT会是更好的选择。

相关推荐
KeepRobots42 分钟前
11-01 温哥华不回拨:用 60 行 Python 查你的工单系统会不会差一小时(KeepRobots 工程笔记)
python
xiao77mwq1 小时前
你以为 OCR 慢?实测 81.3 s 里全是故障代价:如何把「定格态」消掉,让耗时从 6.5 s 到 13 倍差距显出原形
python
深圳市益普科技有限公司1 小时前
半导体良率管理YMS:良率与设备参数的相关性,先拉哪几组数据
人工智能·python·算法
“AI国潮设计-小江”1 小时前
【AIGC实战】Python+SDXL打造“潮汕英歌舞IP”万能立牌插件,批量生成“发财元宝蛋糕”视觉营销方案(附源码)
开发语言·人工智能·python·prompt·aigc
砚底藏山河2 小时前
python量化实操:冷热分层存储
java·开发语言·python·金融
十五年专注C++开发2 小时前
pybind11:一个跨C++和Python平台的编程库
开发语言·c++·python·pybind11
炘爚3 小时前
数据结构算法总结
数据结构·python·算法
信誓旦旦的程序猿3 小时前
【Python量化实战宝典 #18】MACD 金叉死叉手册:DIF、DEA、柱体全拆解(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
Patrick在香港3 小时前
一个加 1 的动作,把最大值变成了最小值
python·numpy·数据类型·整数溢出·数据精度
weixin_BYSJ19873 小时前
电竞先锋网站---附源码02032
java·vue.js·spring boot·python·django·tomcat·php