Django:递归地从“self”`ForeignKey`获取(并计数)相关对象

rqdpfwrv  于 2023-05-19  发布在  Go
关注(0)|答案(2)|浏览(93)

我试图让所有的评论和回复计数收到的帖子,我只有一个模型的帖子,评论和回复。评论是帖子的子项,回复是评论的子项。所有这些都是使用“self”ForeignKey完成的
如何在Python中递归地从父集获取子集(并计算所有子集)?
我有一个父集,它包含一些子集作为它的元素。
我的代码是:

from django.db import models
from django.contrib.auth.models import User
from tld import get_fld
from django.db.models import Q
from django.utils import timezone

class QuestionManager(models.Manager):
    def get_questions(self):
        stories = self.filter(story_type='story')
        stories = self.filter(Q(title__endswith='?'))
        return stories
    

class JobsManager(models.Manager):
    def get_jobs(self):
        stories = self.filter(story_type='story')
        stories = self.filter(Q(title__icontains='hiring') | Q(title__icontains='hire'))
        return stories
    

class NewestManager(models.Manager):
    def get_newest(self):
        stories = self.filter(story_type='story', created_at__day=str(timezone.now().day))
        return stories

class Story(models.Model):

    STORY_TYPE = (
        ('story', 'Story'),
        ('comment', 'Comment'),
        ('reply', 'Reply')
    )
    parent = models.ForeignKey('self', on_delete=models.CASCADE, blank=True, null=True)
    title = models.CharField(max_length=255, null=True, blank=True)
    body = models.TextField()
    url = models.URLField(null=True, blank=True)
    story_type = models.CharField(choices=STORY_TYPE, default='story', max_length=10)
    created_by = models.ForeignKey(User, related_name='story', on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

    ask = QuestionManager()
    jobs = JobsManager()
    new = NewestManager()
    objects = models.Manager()

    class Meta:
        verbose_name_plural = 'stories'

    def __str__(self):
        return f'{self.title} - {self.created_by.username}'
    
    def get_tld(self):
        return get_fld(self.url)
    
    def get_total_comments_count(self):
        pass
    
    def get_root(self):
        root = self
        while root.parent is not None:
            root = root.parent
        return root

我不知道如何才能得到我想要的结果。

ctrmrzij

ctrmrzij1#

可以使用annotate(...)方法将子项计数添加到Story查询集项中:

stories = Story.objects.annotate(comment_count=Count("story")) 
print(stories[0].comment_count)

您还可以通过使用两个下划线(__)连接字段名称来通过多个关系进行引用。你应该也能做

stories = Story.objects.annotate(reply_count=Count("story__story")) 
print(stories[0].reply_count)

Django关于聚合的文档应该会很有帮助

uqcuzwp8

uqcuzwp82#

我找到了一个办法

def get_all_children(self):
    children = list()
    if self.story_type != 'story':
        children.append(self)
    for _ in self.story_set.all():
        children.extend(_.get_all_children())
    return children

然后,在模板中使用长度标签

相关问题