-1

我有一个类似 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() 因为我想总结每个帖子的所有投票并在页面上显示总数。我认为这是最有效的方法。

但是,如果正在查看页面的用户对特定提交进行了投票,我需要以某种方式将该信息传达给模板。我知道我可以遍历模板中的每个投票对象并在那里找出它,但这似乎效率很低。我一直在阅读有关链接查询集的信息。这是我需要在这里做的吗?

4

1 回答 1

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变量

于 2013-10-08T00:17:09.600 回答