首页 > 解决方案 > Django:通过字段关系注释用户的回复计数,以及查询优化

问题描述

我在这个查询集上苦苦挣扎了好几天,这是具有三个类的模型,User, Category, Post

from django.db import models
from django.db.models.deletion import CASCADE

class User(models.Model):
    name = models.CharField()

    @property
    def most_reply_to(self):
        return self.post_setvalues('reply_to')\
            .annotate(reply_to_count=Count('user'))\
            .order_by('user')

    @property
    def most_replied_by(self):
        pass

class Category(models.Model):
    name = models.CharField()

class Post(models.Model):
    title = models.CharField()

    user = models.ForeignKey(on_delete=models.CASCADE)
    category = models.ForeignKey(on_delete=models.CASCADE)

    url = models.URLField()
    reply_to = models.URLField()

reply_to字段Post包含用户交互的信息,不幸的是它不是ForeignKey'ed到Post模型本身,而只是指向url其他post的字段。

我想在这里实现的是用以下内容注释每个用户:

对于该most_reply_to方法,我已经在我的代码中进行了实验,但是代码只给了我对每个单独帖子的回复计数(来自用户),而不是对其他用户的回复总数,我在聚合/在这里注释逻辑。

对于该most_replied_by方法,我知道我需要从整个查询集开始Post.objects.all(),但我不知道应该如何过滤掉那些对此(自我用户)的回复,然后计算按(其他)用户分组的数字。

此外,我应该如何注释每个类别的这两个计数?

非常感谢!

2021 年 4 月 6 日更新

花了几个小时后,我想出了这些方法:

    @property
    def reply_to(self):
        return Post.objects.filter(url__in=self.post_set.values('reply_to'))\
            .values('nick__name')\
            .annotate(reply_to_count=Count('nick__name'))\
            .order_by('-reply_to_count')

    @property
    def replied_by(self):
        return Post.objects.filter(reply_to__in=self.post_set.values('url'))\
            .values('nick__name')\
            .annotate(replied_by_count=Count('nick__name'))\
            .order_by('-replied_by_count')

我不知道我可以使用查询集,即self.post_set,作为查找参数来过滤另一个查询集,即,Post.objects.all()一旦我到达这一点,它就变得简单了。

现在我的问题变成了:这两个查询看起来非常相似(仅交换了urlandreply_to字段),但是它们确实两次访问了我的数据库,而且它们需要很长时间才能在我的数百万行上执行,有没有办法组合和优化他们?

再次感谢!

标签: djangodjango-modelsdjango-queryset

解决方案


推荐阅读