在django中选择过滤的相关对象

时间:2012-09-23 22:02:27

标签: python sql django orm django-orm

我有两个这样的模型(简化):

class Post(models.Model):
    content = models.TextField('content')
    #...

class Vote(models.Model):
    user = ForeignKey(User)
    status = models.TextField(choices = some_choices, default = 'likes')
    post = models.ForeignKey(Post)
    #...

我想要做的是选择(使用一个查询)帖子使用一些过滤器,一个特定的(让我们说当前)用户对这些帖子投票(如果他没有投票就可以),所以我可以输出所有帖子,用户可以看到他喜欢哪些,哪些不是,哪些不投票。

select_related模型的

Vote在这里没有帮助,因为相关的对象无法过滤,所以我想我应该做一些额外的事情,但我无法弄清楚我应该传递什么参数。

所以我猜,它应该是这样的:

Post.objects.filter(content__contains="test").extra(tables="app_vote", where={'my_vote_status': 'something here perhaps?'})

您能否帮我理解如何进行这样的查询?

UPD: schacki提供了一个很好的解决方案,唯一的问题是我希望不同的用户从模板中访问投票,像Post.vote_by_mePost.vote_by_this_user或{{s}一样{1}}

3 个答案:

答案 0 :(得分:2)

好吧,如果你想要答案,有时你应该自己寻找答案:)

以下是我解决问题的方法:

posts = Post.objects.filter(content__contains="test"
    ).extra(select={    
                    #extra selects vote status here for current user
                    "my_vote_status":"""SELECT status FROM blog_vote as vt
                                WHERE vt.user_id = %s
                                AND   vt.post_id = blog_posts.id
                             """ % (request.user.pk) #
    }, tables=['blog_vote'])

UPD:可能没有tables参数

答案 1 :(得分:1)

很难理解你想要什么,但这是另一种尝试。首先,得到你的帖子:

posts = Post.objects.filter(whatever)

现在你想要帖子上一组用户的所有投票,对吗?

votes = Vote.objects.filter(post__in=posts, user__in=users)

现在,您所要做的就是根据用户ID:

将投票与帖子相关联
votes_by_user_by_post = defaultdict(lambda: defaultdict(list))
for v in votes:
    votes_by_user_by_post[post.id][v.user_id].append(v)

for post in posts:
    post.votes_by_user = votes_by_user_by_post[post.id]

在性能方面,可以在两个查询和一些脚本中执行此操作。它们不是复杂的查询,脚本部分只是两个for循环。

答案 2 :(得分:1)

如果我正确理解您的要求,您将需要两个对象传递到上下文中。试试这样,我和other_user必须是有效的用户对象。

posts.vote_by_me=Post.objects.filter(content__contains="test",vote_set__status="something here perhaps?",vote_set__user=me)
posts.vote_by_other_user=Post.objects.filter(content__contains="test",vote_set__status="something here perhaps?",vote_set__user=other_user)