【问题标题】:Left Join on multiple columns Django model ORM foreign key左连接多列 Django 模型 ORM 外键
【发布时间】:2025-12-26 07:55:08
【问题描述】:

我正在尝试了解 Django ORM。

我正在尝试加入 3 个模型。

class User(models.Model):
    id = models.IntegerField(primary_key=True)
    gender = models.CharField(max_length=25)

class Movie(models.Model):
    id = models.IntegerField(primary_key=True)
    title = models.CharField(max_length=300)
    genre = models.CharField(max_length=300)

class Recommendation(models.Model):
    id = models.IntegerField(primary_key=True)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    rec1 = models.ForeignKey(Movie, related_name='rec1', 
     on_delete=models.CASCADE)
    rec2 = models.ForeignKey(Movie, related_name='rec2', 
     on_delete=models.CASCADE)

现在在我的 Recommendation 中,我有 2 个字段是建议(rec1rec2)并对应于 Movie.id。我想加入这些模型,以便能够为每个推荐显示 movie.title 和 movie.genre(对于每个用户,以及他们的用户信息)。

我尝试使用两个外键,但在 related_name 上出现错误,现在出现此错误:Cannot assign "8": "Recommendation.rec1" must be a "Movie" instance. 我认为我不完全理解如何加入这些模型的概念。

在 SQL 中,我会在 rec1 = Movie.idrec2 = Movie.id 上使用 LEFT JOIN,但我不明白如何在 Django ORM 中实现这一点。

预期结果

User 1, gender 'F': recommendations 'Lion King', 'Batman'

【问题讨论】:

  • 那么rec1rec2 不应该是ForeignKeys 吗?通过使用ForeignKey,Django 可以对此进行方便的查询。
  • 是的,我试过了。遇到错误:Cannot assign "8": "Recommendation.rec1" must be a "Movie" instance.,不明白如何规避此问题
  • 正如错误所说,通过使用ForeignKey,您将实例对象设置为这些字段,或者您使用rec1_id 设置该实例的主键。

标签: django orm foreign-keys left-join


【解决方案1】:

Movie 模型使用ForeignKey

class Recommendation(models.Model):
    id = models.IntegerField(primary_key=True)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    rec1 = models.ForeignKey(Movie, related_name="recommendations1")
    rec2 = models.ForeignKey(Movie, related_name="recommendations2")

然后你可以像这样得到你要找的东西,例如:

rec = Recommendation.objects.first()
rec.user.gender
rec.rec1.title

另外,当您将影片分配给rec1rec2 字段时,请确保使用Movie 对象实例:

movie = Movie.objects.first()
rec.rec1 = movie
rec.save()

编辑: 要在拥有 ID 时获取模型对象,您可以执行以下操作:

rec.rec1 = Movie.objects.get(id=row['rec1'])
rec.save()

【讨论】:

  • 好吧,我不知道怎么做最后一部分。当我尝试填写我的推荐模型时,我使用了rec.rec1 = row['rec1'],但我从您的回答中了解到这是不正确的并导致错误。我现在看到我应该弄清楚如何用与Movie.id 匹配的Movie model 实例填充rec.rec1
  • row 包含什么?你如何创建电影对象?
  • row 是我正在循环访问的 Pandas 数据框,其中包含我为该用户所做的 Movie.id 建议。电影对象是从 csv 文件导入和创建的。
  • 在用户进行选择时,具有该 ID 的电影是否存在于数据库中?
  • 是的,它在用户进行选择时确实存在。实际上,我的所有数据(用户、电影和推荐)都是预先存在的,我只是想将其转储到 SQL 数据库中并在视图中显示。我想应该是这个rec.rec1 = Movie.objects.get(id=row['rec1']),现在将测试