【问题标题】:When you have two models connected by a foreignkey in django do you need to do a join?当您在 django 中通过外键连接两个模型时,您需要加入吗?
【发布时间】:2017-06-24 20:33:01
【问题描述】:

Django 文档并没有明确说明这一点,而且它越来越烦人。

观察以下模型:

# models
class Venue(models.Model):
    name = models.CharField(max_length=150, blank=False)
    description = models.CharField(max_length=1000)
    image = models.ImageField(upload_to=imgUnique('venueMedia/venueImages'))
    streetAddress= models.CharField(max_length=100)
    city = models.CharField(max_length=100, blank=False)
    state = models.CharField(max_length=100, blank=False)


class Room(models.Model):
    name = models.CharField(max_length=150, blank=False)
    venue = models.ForeignKey(Venue, related_name='rooms', on_delete=models.CASCADE)
    description = models.CharField(max_length=1000)
    standingCapacity = models.IntegerField
    seatedCapacity = models.IntegerField
    image = models.ImageField(upload_to=imgUnique('venueMedia/venueImages'))

我在房间venue 属性的Room 模型中与Venue 有外键关系。

我需要加入这些表格吗?或者Venue.objects.all() 会自动为我做这件事吗?如果没有,我有如下的原始 sql 这将起作用:

 venueList = Venue.objects.raw('''SELECT *
                              FROM venue_Venue
                              INNER JOIN venue_Room
                              ON venue_Venue_id=venue_Room_id''')

如果不是这样,那么我知道有一个 select_related() 方法,我的理解是我会执行以下操作:

Venue.objects.all().select_related('Room') 

我们能说清楚吗?如您所见,我做了很多研究,但仍然感到困惑

【问题讨论】:

  • venuel.objects.all() 将包含房间对象。您不需要编写原始查询或其他内容。例如venue = Venue.objects.all() nd 如果您想获取房间名称,您可以使用@987654330 @..如果不让我知道,这将起作用
  • 谢谢老兄,这很好

标签: python django orm foreign-key-relationship


【解决方案1】:

select_related

select_related 可以用于选择通过 ForeignKey 或 OneToOne 字段连接的对象,更准确地说,只有当您想选择单个连接的对象时才可以使用。 select_related 接受一个参数,可以使用它来查找related_field。模型属性中指定的参数related_name='rooms' 负责设置相关名称。 select_related 方法搜索这些相关名称,如果找到匹配项,则返回相关对象。这一行

Venue.objects.all().select_related('Room')  

会导致查找错误,因为您没有任何相关名称“房间”但您有 room,因此您还需要注意区分大小写。下面一个就可以了。

Venue.objects.all().select_related('room')

如上所述,select_related 只能用于选择单个相关对象。如果您希望获取多个相关对象,例如 ManyToManyField,请使用 prefetch_related

【讨论】:

  • 但要清楚我不需要使用选择相关。正如@Abi 上面所说,venue.objects.all() 将抓取房间对象。你告诉我,如果我有另一个模型连接到场地,比如设施,但只想要房间模型而不是两者。然后我会使用选择相关。在这种情况下我可以使用 select related 但是由于我只有一个连接的表,它是不必要的,对吧?
  • 是的,这里没有必要使用related_field,但为了提问,我试图解释related_fields。它们可以用于您提到的其他情况。
  • 也许您可以补充一点,select_related 是一种性能优化。它不会影响查询集中的过滤对象,但会影响这些对象的外观。在 SQL 术语中,它将连接模型的字段添加到语句的 SELECT 部分,但不会更改 JOIN 或 WHERE 子句。
猜你喜欢
  • 2020-05-02
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 1970-01-01
  • 2013-09-29
  • 2022-07-04
相关资源
最近更新 更多