Как использовать подзапрос в Django?

Я хочу получить список последних покупок каждого клиента, отсортированный по дате.

Следующий запрос делает то, что я хочу, кроме даты:

(Purchase.objects
         .all()
         .distinct('customer')
         .order_by('customer', '-date'))

Это производит запрос как:

SELECT DISTINCT ON 
    "shop_purchase.customer_id" 
    "shop_purchase.id" 
    "shop_purchase.date" 
FROM "shop_purchase" 
ORDER BY "shop_purchase.customer_id" ASC, 
         "shop_purchase.date" DESC;

Я вынужден использоватьcustomer_id как первыйORDER BY выражение из-заDISTINCT ON.

Я хочу отсортировать по дате, поэтому запрос, который мне действительно нужен, должен выглядеть следующим образом:

SELECT * FROM (
  SELECT DISTINCT ON 
      "shop_purchase.customer_id" 
      "shop_purchase.id" 
      "shop_purchase.date" 
  FROM "shop_purchase" 
  ORDER BY "shop_purchase.customer_id" ASC, 
           "shop_purchase.date" DESC;
  )
AS result 
ORDER BY date DESC;

Я не хочу сортировать с использованием Python, потому что я все еще должен ограничить страницу запроса. В базе данных может быть десятки тысяч строк.

Фактически, в настоящее время он сортируется в python и вызывает очень длительное время загрузки страницы, поэтому я пытаюсь это исправить.

В основном я хочу что-то вроде этогоhttps://stackoverflow.com/a/9796104/242969, Можно ли выразить это с помощью наборов запросов django вместо написания необработанного SQL?

Реальные модели и методы имеют длину в несколько страниц, но вот набор моделей, требуемых для набора запросов выше.

class Customer(models.Model):
  user = models.OneToOneField(User)

class Purchase(models.Model):
  customer = models.ForeignKey(Customer)
  date = models.DateField(auto_now_add=True)
  item = models.CharField(max_length=255)

Если у меня есть данные, такие как:

Customer A - 
    Purchase(item=Chair, date=January), 
    Purchase(item=Table, date=February)
Customer B - 
    Purchase(item=Speakers, date=January), 
    Purchase(item=Monitor,  date=May)
Customer C - 
    Purchase(item=Laptop,  date=March), 
    Purchase(item=Printer, date=April)

Я хочу иметь возможность извлечь следующее:

Purchase(item=Monitor, date=May)
Purchase(item=Printer, date=April)
Purchase(item=Table,   date=February)

На каждого покупателя в списке входит не более одной покупки. Покупка является последней покупкой каждого клиента. Отсортировано по последней дате.

Этот запрос сможет извлечь, что:

SELECT * FROM (
  SELECT DISTINCT ON 
    "shop_purchase.customer_id" 
    "shop_purchase.id" 
    "shop_purchase.date" 
  FROM "shop_purchase" 
  ORDER BY "shop_purchase.customer_id" ASC, 
           "shop_purchase.date" DESC;
) 
AS result 
ORDER BY date DESC;

Я пытаюсь найти способ не использовать сырой SQL для достижения этого результата.

Ответы на вопрос(3)

Ваш ответ на вопрос