【问题标题】:JOIN two tables containing same foreign key in Django在Django中加入两个包含相同外键的表
【发布时间】:2014-09-11 12:42:00
【问题描述】:

所以我有两个模型包含主键“用户”

class Reviews(models.Model):
    subject_user = models.ForeignKey(User,related_name='reviewed_user')
    actor = models.ForeignKey(User)                         ## irrelavent 
    text = models.TextField()

class Friendship(models.Model):
    head_user = models.ForeignKey(User,related_name='followed')
    tail_user = models.ForeignKey(User)                     ## irrelavent 

现在我想查找同样在Friendsip.head_user 中的用户的所有评论。例如,假设用户'1'分别为用户'3'用户'5'

写了一条评论
Reviews:
subject_user_id     actor_id     text
3                   1            LoremIpsum1
5                   1            LoremIpsum2

Friendship:
head_user           tail_user
3                   9
8                   9      ### Irrelavent

现在我输出的应该是与“LoremIpsum1”相对应的评论对象,即其 subject_user 也存在于Friendship.head_user 中的评论对象。我尝试了以下

reviews = Reviews.objects.all().select_related('friendship__head_user')

但它给了我所有的评论

编辑:

这是我插入评论的方式:

review, created = Reviews.object.get_or_create(subject_user=target, actor=actor)
review.text = NewReviewText
review.save()

【问题讨论】:

  • 你怎么已经有了“LoremIpsum1”的Review,或者“8”的Friendship
  • 我没有完全得到你没有得到的东西......User '1'User '3' 写了一条评论“LoremIpsum1”,所以我已经有了条目。
  • 不,该条目存在于数据库中。但是 you 如何在 code 中有它呢?
  • 对不起,我是个菜鸟,但无法解释您的要求。我如何插入评论的代码? (为此编辑了问题):/ #sorry

标签: mysql sql django


【解决方案1】:

如果我理解正确,这应该可以:

heads = (f.head_user for f in Friendship.objects.all())
reviews = Reviews.objects.all().filter("subject_user__in"=heads)

首先你抓取Friendships 中的所有头部用户,然后找到他们的所有评论,这似乎符合你的要求:

我要查找同样在Friendship.head_user的用户的所有评论

您不能使用select_related 的原因是它期望两个模型之间存在明确的关系,而在您的情况下不是ReviewFriendship 之间没有定义外键,所以在这种情况下,最优化的方法可能是我提出的。

但是,在您愤怒地对此进行测试并进行一些分析以确认这是您系统中的一个关键慢点之前,我会注意 Donald Knuth 的话:

我们应该忘记小的效率,比如大约 97% 的时间:过早优化是万恶之源。

【讨论】:

  • 是的。这正是我想要的。但这是最优的吗?喜欢最好的方法吗?
  • “我们应该忘记小的效率,比如说大约 97% 的时间:过早的优化是万恶之源”- Donald Knuth
  • 这使用了一个 python 列表生成器,并将大量数据访问留给了 ORM。在您愤怒地尝试过这个并进行一些分析以确认它是您系统中的一个关键慢点之前,我暂时建议您这样做。
  • 你(或者我应该说 Donald Knuth)刚刚睁开了我的眼睛......谢谢。
  • 我真的希望我能将报价归功于我,但可惜我不能。但是,另一方面是当它们发生时,您应该始终注意效率低下。考虑一个需要 10 秒运行并且可以加速 100 次的方法 - 如果它每天只运行一次是否值得优化,或者还有其他更紧迫的事情可以做吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
相关资源
最近更新 更多