gpt4 book ai didi

python - 按 django 中类似挖掘的评级排序

转载 作者:行者123 更新时间:2023-12-01 06:10:19 24 4
gpt4 key购买 nike

我有两个模型:

class Post(models.Model):
#some fields
pass

class Vote(models.Model):
post = mdoels.ForeignKey(Post)
value = models.IntegerField()

投票值可以是 1 或 -1(用户可以投票赞成或反对)。

如何获取按评分排序的帖子列表?

最佳答案

你必须使用注释。 https://docs.djangoproject.com/en/dev/topics/db/aggregation/

class Post(models.Model):         
name = models.CharField(max_length=20)

class Vote(models.Model):
post = models.ForeignKey(Post)
value = models.IntegerField()
type = models.CharField(max_length=2, choices=(("AW", "Awesomeness"), ("US", "Usefulness")))

然后您需要导入 Sum 并获取按 vote_total 排序的帖子列表,如下所示:

from django.db.models import Sum
Post.objects.annotate(vote_total=Sum('vote__value')).order_by('-vote_total')

编辑:
这是一个例子。创建多个帖子对象和投票对象

Post.objects.get_or_create(id=1, name="post1")
Post.objects.get_or_create(id=2, name="post2")
Post.objects.get_or_create(id=3, name="post3")
Post.objects.get_or_create(id=4, name="post4")
Vote.objects.get_or_create(id=1, post_id=2, value=1, type="AW")
Vote.objects.get_or_create(id=2, post_id=2, value=1, type="AW")
Vote.objects.get_or_create(id=3, post_id=2, value=1, type="US")
Vote.objects.get_or_create(id=4, post_id=2, value=1, type="US")
Vote.objects.get_or_create(id=5, post_id=3, value=-1, type="AW")
Vote.objects.get_or_create(id=6, post_id=3, value=-1, type="AW")
Vote.objects.get_or_create(id=7, post_id=4, value=-1, type="AW")

然后 posts = Post.objects.annotate(vote_total=Sum('vote__value')).order_by('-vote_total') 将导致 [(post.name, post. vote_total) 对于帖子中的帖子] 是。

[(u'post2', 4), (u'post4', -1), (u'post3', -2), (u'post1', None)]

这有一个问题,因为最后没有帖子。由于 django 的 Sum 聚合函数将没有条目的总和视为 None,而不是 0。如果您最初为每个帖子提供值为 0 的投票(或像 reddit 的系统一样值为 1),则可以解决这个问题,您将没有得到 None:例如:

for p in Post.objects.all():
Vote.objects.get_or_create(post_id=p.id, value=0)

然后你会得到

>>> [(p.name, p.vote_total) for p in
Post.objects.annotate(vote_total=Sum('vote__value')).order_by('-vote_total')]
[(u'post2', 4), (u'post1', 0), (u'post4', -1), (u'post3', -2)]
<小时/>

编辑:根据有关不同投票类型的评论,将类型添加到投票模型(上面完成)。您应该能够执行类似的操作(将“yourappname”替换为应用程序的名称以获得正确的数据库表):

select_dict = dict(vote_total = "SELECT SUM(value) FROM yourappname_vote WHERE yourappname_vote.post_id = yourappname_post.id",
awesome_total = "SELECT SUM(value) FROM yourappname_vote WHERE yourappname_vote.post_id = yourappname_post.id AND yourappname_vote.type = 'AW' ",
useful_total = "SELECT SUM(value) FROM yourappname_vote WHERE yourappname_vote.post_id = yourappname_post.id AND yourappname_vote.type = 'US' ",)

posts = Post.objects.all().extra(select = select_dict).order_by('-vote_total')

>>> [(p.name, p.vote_total, p.awesome_total, p.useful_total) for p in posts]
[(u'post2', 4, 2, 2),
(u'post1', 0, 0, 0),
(u'post4', -1, -1, 0),
(u'post3', -2, -2, 0)]

现在,每个帖子在对数据库的一次查询中都会有一个 vote_totalawesome_totaluseful_total。比 ORM 丑一点,但仍然具有很强的可读性(这就是 Sum 聚合的工作原理。)。您仍然需要对每个类别的投票进行初始投票,以通过无顺序出现的投票。

关于python - 按 django 中类似挖掘的评级排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6255591/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com