使用django过滤和计数

时间:2015-10-03 12:03:50

标签: django django-models

假设我有一个帖子和投票表。 每个帖子都可以是喜欢的或不喜欢的(这是post_type)。

class Post(models.Model):
    author = models.ForeignKey(User)
    title = models.CharField(verbose_name=_("title"), max_length=100, null=True, blank=True)
    content = models.TextField(verbose_name=_("content"), unique=True)
    ip = models.CharField(verbose_name=_("ip"), max_length=15)


class Vote(models.Model):
    user = models.ForeignKey(User)
    post = models.ForeignKey(Post)
    post_type = models.PositiveSmallIntegerField(_('post_type'))

我想收到帖子,并在每个帖子上添加喜欢的数量。 这样做的最佳方式是什么?

2 个答案:

答案 0 :(得分:0)

您应该在Post模型中创建一个函数,并在需要计数时调用它。

class Post(models.Model):
    ...
    def likes_count(self):
        return self.vote_set.filter(post_type=1).count()

像这样使用:

p = Post.objects.get(pk=1)
print p.likes_count()

答案 1 :(得分:0)

一种方法是向Post类添加一个获取此计数的方法,如@ sachin-gupta所示。但是,这将为您获取的每个帖子生成一个额外的查询。如果你是批量提取帖子及其数量,这是不可取的。

您可以批量注释帖子,但我不认为您当前的模型结构会允许它,因为您无法在注释中进行过滤。您可以考虑按如下方式更改结构:

class Vote(models.Model):
    """
    An abstract vote model.
    """

    user = models.ForeignKey(User)
    post = models.ForeignKey(Post)

    class Meta:
        abstract = True


class LikeVote(Vote)
    pass


class DislikeVote(Vote)
    pass

即,不是在一个模型中存储好恶,而是为每个模型分别设置模型。现在,您可以在一个查询中批量注释您的帖子:

from django.db.models import Count    

posts = Post.objects.all().annotate(Count('likevote_set'))

for post in posts:
    print post.likevote__count

当然,这是否可行取决于你应用程序其余部分的架构,以及有多少"投票类型"你打算有。但是,如果您要经常查询帖子的投票数,那么您将需要尝试避免大量的数据库查询。