我有两个这样的模型(简化):
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_me
和Post.vote_by_this_user
或{{s}一样{1}}
答案 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)