2011-02-08 31 views
6
class Log: 
project = ForeignKey(Project) 
msg = CharField(...) 
date = DateField(...) 

我想選擇四個最近的日誌條目,其中每個日誌條目必須具有唯一的項目外鍵。我已經嘗試在谷歌搜索的解決方案,但他們沒有工作和Django文檔不是用於查找非常好的..Django:不同的外鍵

我嘗試這樣的東西:

Log.objects.all().distinct('project')[:4] 
Log.objects.values('project').distinct()[:4] 
Log.objects.values_list('project').distinct('project')[:4] 

但這要麼返回Nothing或同一個項目的日誌條目..

任何幫助,將不勝感激!

回答

9

查詢不像那樣工作 - 無論是在Django的ORM還是在底層的SQL中。如果你想獲得唯一的ID,你只能查詢ID。所以你需要做兩個查詢來獲取實際的日誌條目。喜歡的東西:

id_list = Log.objects.order_by('-date').values_list('project_id').distinct()[:4] 
entries = Log.objects.filter(id__in=id_list) 
+0

謝謝你的回答,unfortuatly ID_LIST = Log.objects.order_by( ' - 日期')。values_list( 'PROJECT_ID')不同的() ..不起作用。它沒有理清不同的。它工作,如果我刪除鏈中的order_by(),但它不是按日期排序... – mrmclovin 2011-02-09 08:34:44

+0

它仍然無法正常工作..沒有幫助嗎? – mrmclovin 2011-02-22 19:58:42

3

其實,你可以得到project_ids在SQL。假設你想爲這四個項目的最新日誌條目的唯一項目ID,則SQL是這樣的:現在

SELECT project_id, max(log.date) as max_date 
FROM logs 
GROUP BY project_id 
ORDER BY max_date DESC LIMIT 4; 

,你真正想要的所有日誌信息。在PostgreSQL 8.4和更高版本可以使用窗口函數,但不會對其他版本/數據庫工作,所以我會做更復雜的方式:

SELECT logs.* 
FROM logs JOIN (
    SELECT project_id, max(log.date) as max_date 
    FROM logs 
    GROUP BY project_id 
    ORDER BY max_date DESC LIMIT 4) as latest 
ON logs.project_id = latest.project_id 
    AND logs.date = latest.max_date; 

現在,如果你有訪問窗口的功能,這是一個有點整潔(我想反正),當然更快地執行:

SELECT * FROM (
    SELECT logs.field1, logs.field2, logs.field3, logs.date 
     rank() over (partition by project_id 
        order by "date" DESC) as dateorder 
    FROM logs) as logsort 
WHERE dateorder = 1 
ORDER BY logs.date DESC LIMIT 1; 

好吧,也許這不是更容易理解,但把我的話,它運行的世界大型數據庫上更快。

雖然我不完全確定它是如何轉換爲對象語法的,或者甚至是如此。另外,如果您想獲取其他項目數據,則需要參加項目表。