我有一个类似reddit的应用程序。有“帖子”,人们对它们进行投票或投票。在我的模板中,我列出了所有帖子,我希望能够表明此人是否已经在帖子上投票。
这有点令人困惑,因为我将我的查询集中的帖子全部传递给模板,但是当我遍历每个帖子以显示它时,我也想知道是否存在现有的投票。
以下是一些代码:
class Submission(models.Model):
submitter = models.ForeignKey(User)
title = models.CharField("Title", max_length=200)
class Vote(models.Model):
voter = models.ForeignKey(User)
submission = models.ForeignKey(Submission)
vote_value = models.FloatField()
class SubmissionListView(ListView):
model = Submission
queryset = Submission.objects.extra(select={'total': 'IFNULL((SELECT SUM(vote_value) ' + \
'FROM submissions_vote ' + 'WHERE submissions_vote.submission_id = ' + 'submissions_submission.id), ' + \
'0)'}).order_by('-total')
paginate_by = 5
好的,你可以看到我正在做一个查询集extra()因为我想总结每个帖子的所有投票并在页面上显示总数。我认为这是最有效的方法。
但是,如果正在查看该页面的用户对特定提交进行了投票,我需要以某种方式将该信息传达给该模板。我知道我可以循环遍历模板中的每个投票对象并在那里找出它,但这似乎效率很低。我一直在阅读关于链接查询集的内容..这就是我需要在这里做的事情吗?
答案 0 :(得分:2)
您可以添加另一个extra
选择:
queryset = Submission.objects.extra(
select={'total': 'IFNULL((SELECT SUM(vote_value) ' + \
'FROM submissions_vote ' + 'WHERE submissions_vote.submission_id = ' + \
'submissions_submission.id), ' + '0)',
'has_voted': 'CASE WHEN %d IN (SELECT voter_id FROM submissions_vote WHERE ' + \
'submissions_vote.submission_id = submissions_submission.id) THEN 1 ELSE 0 END'
}, select_params=(self.request.user.pk,)).order_by('-total')
我知道这不是最漂亮的解决方案。我经常尝试不经常编写自定义sql,但我无法想到更好的东西。很想知道你最终做了什么。
编辑:由于您需要访问self.request,因此需要覆盖get_queryset
方法:
def get_queryset(self):
return Submission.objects.extra(
select={'total': 'IFNULL((SELECT SUM(vote_value) ' + \
'FROM submissions_vote ' + 'WHERE submissions_vote.submission_id = ' + \
'submissions_submission.id), ' + '0)',
'has_voted': 'CASE WHEN %d IN (SELECT voter_id FROM submissions_vote WHERE ' + \
'submissions_vote.submission_id = submissions_submission.id) THEN 1 ELSE 0 END'
}, select_params=(self.request.user.pk,)).order_by('-total')
这样做而不是queryset
变量