Как выполнить обратное соединение в Django ORM? Точно так же, как select_related, но в обратном порядке

Примеры моделей:

class Order(models.Model):
    order_number = models.CharField(max_length=20)
    customer = models.CharField(max_length=100)

class OrderItem(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    product = models.CharField(max_length=100)
    quantity = models.IntegerField()

    class Meta:
        unique_together = ('order', 'product')

Между Order и OrderItem существует отношение unique_together, но ограничение на ('order', 'product') гарантирует, что для каждого заказа может быть только один товар на товар.

Я хочу получить все заказы для определенного клиента, которые содержат определенный продукт (скажем, 'Laptop'), вместе с этим конкретным OrderItem.

На языке SQL это выглядело бы так:

SELECT * 
FROM order
JOIN orderitem 
  ON order.id = orderitem.order_id 
  AND orderitem.product = 'Laptop'
WHERE order.customer = 'John Doe';

В Django ORM, prefetch_related делает это в двух запросах, но это неэффективно из-за большого набора результатов и фильтрации. Я хочу знать, как сделать это в одном запросе, используя select_related или аналогичный метод для применения фильтра в самом JOIN.

Как я могу этого добиться? Приведенные выше модели предназначены для упрощенной демонстрации, но реальный случай использования, о котором я говорю, включает миллионы строк, поэтому строго необходимо, чтобы это был один запрос с join, и я так запутался, как я не могу сделать такой простой join с помощью Django ORM.

Вы нашли это?

Order.objects.filter(customer='John Doe', orderitem__product='Laptop')
Вернуться на верх