如何使用Django从一个查询中选择多个表?

tdo*_*sen 11 python django join django-queryset

我有两张桌子,一张是"公司",一张是"员工":

class Company(models.Model):
    name = models.CharField(max_length=60)

class Employee(models.Model):
    name = models.CharField(max_length=60)
    company = models.ForeignField(Company)
Run Code Online (Sandbox Code Playgroud)

我想在表格中列出每个员工,旁边有公司.这很简单,通过调用employees = Employee.objects.all()和模板循环来调用它{{employee.company.name}}.

此解决方案的问题是它将为循环中的每个项创建一个新查询.因此,对于每个员工,将向公司发出一个查询,如下所示:

SELECT `company`.`id`, `company`.`name`
FROM `company`
WHERE `company`.`id` = 1 # This will of course be the employee.company_id
Run Code Online (Sandbox Code Playgroud)

相反,我希望最初在获取Employees的同一查询中进行此连接.像这样的东西:

SELECT `employee`.`name` AS `name`,
       `company`.`name` AS `company_name`
FROM `employee` INNER JOIN `company` ON `employee`.`company_id` = `company`.`id`
Run Code Online (Sandbox Code Playgroud)

这是否可以使用Django QuerySet?如果没有,有没有办法解决这个问题(没有原始的sql)?或者是否应忽略此行为,缓存并将其视为"优化"?

Ign*_*ams 24

使用 select_related() 将预先填充适当的属性:

Employee.objects.select_related()
Run Code Online (Sandbox Code Playgroud)


mak*_*puf 8

我想你要查找的是查询集的select_related方法.见文档

select_related()

返回一个QuerySet,它将自动"跟随"外键关系,在执行查询时选择其他相关对象数据.这是一个性能提升器,它会导致(有时很多)更大的查询,但意味着以后使用外键关系不需要数据库查询


Ken*_*Ken 8

这是一个老问题,让我提供一个新的答案.

实际上,你可以这样做:

employees = Employee.objects.all().values('id','name','company__name')
Run Code Online (Sandbox Code Playgroud)

然后,Django将自动查找Company类并为您找到公司名称.

在模板页面上,使用{{employee.company__name}}然后它将正确显示公司名称.

  • 这是一个老问题,很高兴你回答了这个问题。我一直在循环尝试从与两个表具有一对多关系的基表创建查询。`select_related()` 对我没有帮助,除非我只对一张表中的相关数据感兴趣;然而,这很容易适应我的情况,而且效果很好! (2认同)