【发布时间】:2021-10-02 21:36:14
【问题描述】:
我正在创建一个 Reddit 克隆,目前正在尝试实现帖子排序功能。我坚持按“最多投票”对帖子进行排序。我相信我的模型/数据库结构不正确,并希望我不必重做它,因为我的投票系统运行良好。
// models.py
class Post(models.Model):
title = models.CharField(max_length=300)
content = models.TextField()
date_created = models.DateTimeField(verbose_name="date_created", auto_now_add=True)
date_edited = models.DateTimeField(verbose_name="date_edited", auto_now=True)
author = models.ForeignKey(User, related_name="posts", on_delete=models.CASCADE)
subreddit = models.ForeignKey(Subreddit, on_delete=models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(fields=["title", "subreddit"], name="sameTitle_in_sameSubreddit_notAllowed")
]
def __str__(self):
return self.title
class Vote(models.Model):
original_post = models.ForeignKey(Post, related_name="post_votes", on_delete=models.CASCADE, null=True)
original_comment = models.ForeignKey(Comment, related_name="comment_votes", on_delete=models.CASCADE, null=True)
owner = models.ForeignKey(User, related_name="votes", on_delete=models.CASCADE)
vote_choice = models.IntegerField(choices=((1, "UP"), (2, "DOWN")))
class Meta:
constraints = [
models.UniqueConstraint(fields=["original_post", "owner"], name="sameOwner_samePost_notAllowed"),
models.UniqueConstraint(fields=["original_comment", "owner"], name="sameOwner_sameComment_notAllowed")
]
查看“投票”模型,我能够在视图(测试目的)中编写原始 SQL 查询,该查询将“original_post”列按最高投票数排序并将其返回到列表中。是否可以获取此查询的结果并将自定义排序应用于“发布”查询集。因此,例如,按“post_id”对帖子进行排序,但按照“最多投票列表”的相同顺序对 iD 进行排序。
// views.py
class PostWithMostUpVotes(viewsets.ModelViewSet):
def list(self, request, *args, **kwargs):
queryset = Vote.objects.raw("SELECT id, original_post_id FROM reddit_api_vote WHERE original_post_id IS NOT NULL AND vote_choice='1' GROUP BY original_post_id ORDER BY count(vote_choice) DESC;")
serializer = VoteSerializer(queryset, many=True)
sorted_list = []
for x in serializer.data:
sorted_list.append(x["original_post"])
return Response(sorted_list)
我用 Postman 测试了上述视图,它确实按预期工作。
// urls.py
router.register('mostupvotes', PostWithMostUpVotes, 'mostupvotes')
original_post 9 个帐户获得最多支持。仅供参考:1=赞成,2=反对 iD 为 9 的帖子获得最多赞,因此它出现在列表的开头。
【问题讨论】: