django - 如何在自引用外键中使用现有查询引用所有子对象?

标签 django django-models

我有一个代表所有者的模型。该模型自身有一个外键来表示父实体。还有另一种模型,称为具有所有者外键的 Assets 。母公司外键的目的是模拟公司结构,以便母公司“拥有”外键为其自身或子公司的 Assets :

Class Owner(models.Model):
    parent = models.ForeignKey(
                 “self”,
             )

Class Asset(models.Model):
    owner = models.ForeignKey(
                 Owner,
             )

有没有办法通过简单地引用父级(例如 Asset.object.filter(owner=parent))来返回父级及其所有子公司拥有的所有 Assets ?我知道我可以创建一个方法来返回父级所有子公司的查询集,然后过滤到该所有者查询集中的所有 Assets ,但我希望避免大规模重构,因为现有的代码库没有以下概念:父所有者。

我的第一个想法是自定义管理器,但我认为这不会改变默认管理器之外的现有查询的行为。我可以在该型号上重载过滤器吗?如果我需要重新思考设计,那很好,但我认为这种方法更干净并且捕获了我们想要的行为。谢谢!

最佳答案

可能不是一个令人满意或完整的答案,但我有一个原始的 postgres 查询,它在单个查询中返回父级的所有子级。它使用 recursive query

class Owner(models.Model):
    parent = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True)

    def get_all_children(self):
        return Owner.objects.raw(f"""
            with recursive t(id, parent_id) as
            (
                select id, parent_id
                from app_owner where id={self.id}
                union all
                select b.id, b.parent_id
                from app_owner b
                join t on b.parent_id=t.id
            )
            select * from t
        """)

这也可以用来过滤 Assets

Asset.objects.filter(owner__in=Owner.objects.get(id=1).get_all_children())

关于django - 如何在自引用外键中使用现有查询引用所有子对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69958880/

相关文章:

python - 有没有更简洁的方法来使用 Django ORM 链接过滤器?

Django 分页器 : where does paginator modify SQL query adding LIMIT/OFFSET?

jquery - templateResult 和 templateSelection 的 Select2 参数不同 (django)

javascript - 在 HTML 和 Javascript 中使用 if else 语句插入文本

python - 如何在 Django 中运行 python 脚本?

Django prefetch_相关查询未按要求工作,需要进行故障排除

python - 限制每个用户对每本书的单一评分 : Django ORM

django - 模块未找到错误: No module named 'win32api' right after I install channels

python - 将整数(最多 2^48)安全加密为最短的 URL 安全字符串

python - 如何在 Django Rest Framework 序列化程序中捕获 sql 错误?