Python 如何访问反向关系django的反向关系
我决定尝试让所有其他用户回复与给定回复相同的评论。我已经提出了下面的python,但是我担心这将执行不止一个DB调用Python 如何访问反向关系django的反向关系,python,django,python-3.x,django-models,django-queryset,Python,Django,Python 3.x,Django Models,Django Queryset,我决定尝试让所有其他用户回复与给定回复相同的评论。我已经提出了下面的python,但是我担心这将执行不止一个DB调用 other_repliers = [other_reply.user for other_reply in my_reply.comment.replies.filter()] 我正在寻找一个一分贝的呼叫修复。 Psuedo SQL逻辑类似于: SELECT u.* FROM users AS u INNER JOIN replies AS r ON r.user =
other_repliers = [other_reply.user for other_reply in my_reply.comment.replies.filter()]
我正在寻找一个一分贝的呼叫修复。
Psuedo SQL逻辑类似于:
SELECT u.*
FROM users AS u
INNER JOIN replies AS r
ON r.user = user.id
WHERE r.comment = {my_reply.comment}
AND r.user != {my_reply.user}
有人知道我可以在python django命令链中执行上述SQL的方法吗
编辑: 当你忽略任何非关系的东西时,我的模型是这样的:
class Comment(models.Model):
user = models.ForeignKey(User, related_name='comments')
listing = models.ForeignKey(Listing, related_name='comments')
class CommentReply(models.Model):
user = models.ForeignKey(User, related_name='replies')
comment = models.ForeignKey(Comment, related_name='replies')
class User(models.Model):
pass
编辑:我希望在下图中收集最后一列:
/--- r4 --- u4
/
r1 --- c1 --- r3 --- u3
\
\--- r2 --- u2
*
** r1
其中r*为请求,c*为注释,u*为用户
星号线表示r1被忽略(因为它被用来查找其他r*s)。我发现了以下django命令链,有没有更优雅的解决方案
User.objects.filter(id__in=my_reply.comment.replies.values_list('user_id')) \
.exclude(id=my_reply.user)
但对我来说,这看起来像是两个查询。我不确定使用django API的单个查询是否可行,但两个查询应该都可行。您的常用元素是
注释
。首先让我们得到所有的回复r1,r2,r3,r4。。。对这一评论:
all_replies = CommentReply.objects.filter(comment=my_reply.comment)
现在我们只需要这些回复中的用户
users = User.objects.filter(replies__in=all_replies)
您还可以使用:
这将使用联接在单个查询中检索所有用户。列表理解只是将那些已经检索到的用户重新打包为用例所需的格式
旁注:如果您关心检索(但不使用)可能较大的注释正文,您可以始终在查询中插入
.defer('body\u field\u name')
。您还可以使用双下划线表示法延迟用户未使用的字段(如果需要)。您可以提供您的模型定义吗?我已经剥离了(我假设的)不相关的字段。如果您认为我缺少解决此问题的关键信息,请说。print(my_reply.comment.repries.filter().query)
查看django如何编写查询。还可以让您分析所有发出的sql。嘿@cowbert这真的很酷(总是想知道如何访问sql查询),但这只能说明我能做什么。不是我想做的吗?我遗漏了什么吗?它会告诉你django正在生成什么,这将帮助你找出你需要在模型中修改什么来优化它。噢,我没有考虑这种关系,很好的发现。这是一个子查询,而不是两个单独的查询。不过,可能有一种方法可以通过连接来实现。
replies_with_users = CommentReply.objects.filter(comment_id=my_reply.comment_id) \
.exclude(user=my_reply.user) \
.select_related('user')
users = [reply.user for reply in replies_with_users]