【问题标题】:Django select filtered related objectDjango选择过滤的相关对象
【发布时间】:2021-10-14 14:30:47
【问题描述】:

我有 3 个模型:

class ForumTopic(models.Model):
    author          = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    title           = models.CharField(max_length=100) 

class ForumMessage(models.Model):
    topic           = models.ForeignKey(ForumTopic, on_delete=models.CASCADE)
    author          = models.ForeignKey('auth.User', on_delete=models.CASCADE)

class ForumMessageVote(models.Model):
    user            = models.ForeignKey('auth.User',    on_delete=models.CASCADE)
    message         = models.ForeignKey(ForumMessage,   on_delete=models.CASCADE)
    vote          = models.IntegerField(default=0)

我想为特定 ForumTopic 选择所有 ForumMessage 并附加到由特定 User 过滤的此查询 ForumMessageVote 的结果strong> 和当前 ForumMessage

我该怎么做?

【问题讨论】:

    标签: python-3.x django join orm


    【解决方案1】:

    我认为您需要过滤 ForumMessageVote 对象

    您需要的信息将通过查询集的结果提供

    ForumMessageVote.objects.filter(
        user = the_selected_user, 
        message__topic = the_selected_topic 
    ).select_related(
        'message', 'message__topic' )
    

    如果您已经知道用户或主题的 ID,例如通过 URL,那么您可以过滤 user_id=uidmessage__topic_id=tid

    【讨论】:

    • 我想遍历模板中的所有消息并获得当前用户对每条消息的投票。
    • 好的。谢谢,我试试这个。
    • 嗯...但是 ForumMessageVote 对象可能会丢失(如果用户从不投票消息)
    • 是的。我认为,如果您想包含用户未投票的对象,您将需要多个数据库查询。就像 Hamid Rajabi 的回答一样。
    【解决方案2】:

    由于您对投票和消息使用了两种不同的模型,因此您进行了两个相关查询:

    ForumMessages= ForumMessage.objects.filter(topic="specificTopic")
    ForumMessageVotes=ForumMessageVote.object.filter(message__in=ForumMessages)
    

    但是,我看不出有什么理由不使用“投票”作为“消息”模型的属性;它将减少冗余。

    【讨论】:

    • 我认为使用这个作为后备方法,当在模板的循环中显示所有消息的消息时,检查投票是这个消息。
    • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。您可以在帮助中心找到更多关于如何写好答案的信息:stackoverflow.com/help/how-to-answer。祝你好运?
    【解决方案3】:

    我找到了一个带有子查询的解决方案(我在 python 控制台中检查过,它可以工作):

    vote=ForumMessageVote.objects.filter(message=OuterRef("pk")).filter(user=request.user)
    messages=ForumMessage.objects.all().annotate(user_vote=Subquery(vote.values('vote')[:1]))
    

    如何获得投票:

    v=messages.objects.get(author=request.user).user_vote
    

    在模板中:

    {% for msg in messages %}
    {{msg.user_vote}}
    {% endif %}
    

    【讨论】:

      猜你喜欢
      • 2012-09-15
      • 2010-09-20
      • 2019-02-14
      • 2018-11-18
      • 2012-11-29
      • 1970-01-01
      相关资源
      最近更新 更多