Как выбрать из нескольких таблиц в одном запросе с помощью Django?

У меня есть две таблицы, одна "Компания" и один "Сотрудник":

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

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

И я хочу перечислить каждого Сотрудника в таблице, рядом с Компанией. Это достаточно просто, вызывая 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

Вместо этого я хочу сделать это соединение изначально в том же запросе, получая Рабочих. Что-то вроде этого:

SELECT `employee`.`name` AS `name`,
       `company`.`name` AS `company_name`
FROM `employee` INNER JOIN `company` ON `employee`.`company_id` = `company`.`id`

Возможно ли это с помощью Django QuerySet? Если нет, есть ли способ, с которым я могу работать, чтобы решить это (без сырого sql)? Или следует игнорировать это поведение, кэшировать и считать "оптимизированным"?

Ответ 1

Использование select_related() предварительно заполнит соответствующие атрибуты:

Employee.objects.select_related()

Ответ 2

Я думаю, что вы ищете, это метод select_related вашего набора запросов. Смотрите документ

select_related()

Возвращает QuerySet, который будет автоматически "следить" за внешним ключом отношения, выбирая что дополнительные данные связанного объекта, когда это выполняет свой запрос. Это повышение производительности, которое приводит к (иногда намного) большие запросы, но означает дальнейшее использование внешнего ключа отношения не требуют базы данных запросы

Ответ 3

Это старый вопрос, позвольте мне дать новый ответ.

Собственно, вы можете сделать это:

employees = Employee.objects.all().values('id','name','company__name')

тогда Django автоматически ищет класс компании и найдет для вас название компании.

на странице шаблона используйте {{employee.company__name}}, тогда он отобразит название компании правильно.

Ответ 4

С необработанными запросами

    qry1 = "SELECT c.car_name, p.p_amount FROM pay p, cars c where p.user_id=%s;"

    cars = Cars.objects.raw(qry1, [user_id])