Django选择过滤的相关对象

Posted

技术标签:

【中文标题】Django选择过滤的相关对象【英文标题】:Django select filtered related object 【发布时间】: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

我该怎么做?

【问题讨论】:

【参考方案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)

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

【讨论】:

我认为使用这个作为后备方法,当在模板的循环中显示所有消息的消息时,检查投票是这个消息。 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。您可以在帮助中心找到更多关于如何写好答案的信息:***.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 %

【讨论】:

以上是关于Django选择过滤的相关对象的主要内容,如果未能解决你的问题,请参考以下文章

基于外键过滤数据 - Django

Django ORM - 通过多个相关对象和 Q 查询选择

Django - 过滤相关对象

Django 按最新的相关对象过滤

Kettle实战之(2)过滤记录

如何使用附加过滤的相关对象作为 Django 中的字段来获取结果?