2011-08-11 103 views
7

是否有一種簡單的方法可以基於哪個記錄具有列中的最大/最小值來過濾Django查詢?我基本上要求thesequestions,但在Django的ORM的具體上下文。根據最大列值的記錄過濾Django查詢

例如

說我有一個模型,旨在存儲每個人的電話號碼的歷史價值。

class Person(models.Model): 
    name = models.CharField(max_length=100) 
    phone = models.CharField(max_length=100) 
    created = models.DateTimeField(auto_now_add=True) 

與記錄:

Person(name='Jim',phone='123-456-9870', created=datetime(2005,1,2,4,2)) 
Person(name='Jim',phone='329-802-9870', created=datetime(2006,9,2,7,8)) 
Person(name='Sue',phone='324-345-3450', created=datetime(2008,7,4,6,1)) 

現在說我想找到每個人的最近的電話號碼。

在SQL中,我通常要使用子查詢來計算的最大值:

SELECT p1.name, p1.phone, p1.created 
FROM person_person p1, (
    SELECT name, MAX(created) AS max_created 
    FROM person_person 
    GROUP BY name 
) AS p2 
WHERE p1.name = p2.name AND p1.created = p2.max_created 

是否有Django的任何機制,可以簡化這個?

我在後端使用PostgreSQL,所以任何依賴於PostgreSQL特定功能的想法或解決方案都會有幫助。

+0

它看起來在django上你不能做你正在尋找的東西,除非你使用原始查詢sql。檢查[this](https://docs.djangoproject.com/en/dev/ref/models/querysets/#distinct)。由於此刻你添加了一個order_by('created'),該order_by被添加到查詢中的select中,所以distinct將不會執行任何操作。 – Hassek

回答

4

您可能只想在這裏使用原始SQL,raw()管理器方法有助於實現此目的,從而允許您從查詢中返回模型實例。唯一的竅門是原始查詢需要包含主鍵。這也許應該爲你工作(除非你有主鍵設置爲id其他東西):

latest_phone_numbers = Person.objects.raw(''' 
SELECT p1.id, p1.name, p1.phone, p1.created 
FROM person_person p1, (
    SELECT name, MAX(created) AS max_created 
    FROM person_person 
    GROUP BY name 
) AS p2 
WHERE p1.name = p2.name AND p1.created = p2.max_created 
''') 
1

如果你的後端是PostgreSQL的Roman Pekar給了一個很好的答案this問題。