【问题标题】:Loading tree of relations at once一次加载关系树
【发布时间】:2013-01-17 23:26:35
【问题描述】:

我有一个名为 Post 的模型:

class Post(models.Model):
    poster = models.ForeignKey(User)
    content = models.TextField(verbose_name='Text', max_length=1000)
    reply_to = models.ForeignKey('self', null=True, blank=True, default=None)   

这允许添加“第一个帖子”(带有空白的reply_to),并回复帖子甚至“回复回复”

例如,我的数据库中有这样的内容:

First Post
    Reply one
        Reply to reply one
    Reply two
        Reply to reply two

如何加载回复树?

当我使用时:

r = Post.objects.filter(reply_to=FirstPost)

它当然会返回:

Reply one
Reply two

是否可以一次加载所有相关帖子? 我主要需要它来计算对第一篇文章的所有回复。

【问题讨论】:

    标签: python django django-queryset django-orm


    【解决方案1】:

    您可以使用 MPTT (http://django-mptt.github.com/django-mptt/tutorial.html#the-problem)。我以前没有使用过这个库,所以让我知道它是怎么回事。

    models.py

    class Post(MPTTModel):
        poster = models.ForeignKey(User)
        content = models.TextField(verbose_name='Text', max_length=1000)
        parent = models.TreeForeignKey('self', null=True, blank=True, related_name='children')
        class MPTTMeta:
            order_insertion_by = ['poster']
    

    views.py

     ....
     r = FirstPost.get_children()
    

    【讨论】:

    • 酷,这实现了我在一个简单的附加包中提倡的。
    • 对了,我以前用过这个应用,@victor 的响应很中肯。
    • 看起来很棒!我会尽快尝试。
    • @Victor'Chris'Cabral 我必须告诉你:MPTT 效果很好。我认为它应该默认在 Django 中。顺便说一句,我需要的函数是 get_descendants(),而不是 get_children()。无论如何,谢谢你。
    • 太棒了。我很高兴它运作良好。你的项目是开源的吗?或者你能发布一些代码吗?
    【解决方案2】:

    不,我认为没有办法一次加载所有回复。

    但是,您可以向帖子类型添加额外的元数据,以便能够运行有序样式的查询,其中计算回复的数量变成了一个简单的计算,其中数据已经为父节点加载。

    请参阅this article 了解如何做到这一点(它使用 MySQL SQL 方言和 PHP,但原则仍然适用)。

    基本上,您将leftright 字段添加到树中定义排序的节点,让您轻松计算树中给定根元素下方 的项目数。它就像数据库表中的二叉树。原理取自这本优秀的数据库设计书籍:"Joe Celko's Trees and Hierarchies in SQL for Smarties"

    【讨论】:

      猜你喜欢
      • 2021-10-27
      • 2011-02-24
      • 2013-10-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      相关资源
      最近更新 更多