Django查询集和外键

时间:2013-10-07 23:17:20

标签: python django

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

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

1 个答案:

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