【问题标题】:Selecting filtered related objects in django在 django 中选择过滤的相关对象
【发布时间】:2012-09-15 10:01:27
【问题描述】:

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

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 for 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_userPost.vote_by_top_user

【问题讨论】:

  • 您如何关联PostVote?你从你的例子中遗漏了一些重要的东西
  • 哎呀,你是对的。感谢您指出这一点,我已经添加了与问题的关系。

标签: python sql django orm django-orm


【解决方案1】:

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

这是我解决问题的方法:

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 参数也可以工作

【讨论】:

    【解决方案2】:

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

    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 个或更多不同用户的投票并将它们保存为 Post 的不同变量(典型情况是查看某人对帖子的投票和在同一视图中查看您对同一帖子的投票)
    • 这并不是我想要这样做的唯一原因,但这个故事有点长:)
    • 您能否更详细地解释一下您想要做什么,而不是假设它必须额外完成。这将有助于所有人提出最佳解决方案。请用您自己的话描述您想要检索的内容。
    • 是的,需要更多信息。为什么你不能只做user__in=,然后遍历结果、提取帖子、手动设置变量等等?
    • 如果我可以选择所有我想要的东西,我为什么要迭代?问题是我不确定如何正确地做到这一点:)
    【解决方案3】:

    如果我正确理解您的要求,您将需要两个对象来传递到上下文中。像这样尝试,其中 me 和 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)
    

    【讨论】:

    • 谢谢,这是一个很好的解决方案,唯一的问题是我想在模板中引用访问此投票。 Post.vote_by_me 和 Post.vote_by_this_user 之类的东西
    • 还有一个问题——没有指定用户的投票,它不会返回帖子
    • 对不起,那我好像不太明白你的要求;如果您想要一个正确的答案,请提供更多详细信息,我们无法猜测。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 2019-02-14
    • 2012-11-29
    • 2018-11-18
    相关资源
    最近更新 更多