2010-09-17 40 views
37

我有一個模型:Django的查詢使用.order_by()和.latest()

class MyModel(models.Model): 
    creation_date = models.DateTimeField(auto_now_add = True, editable=False) 

    class Meta: 
     get_latest_by = 'creation_date' 

我曾在我看來,一個查詢做了以下內容:

instances = MyModel.objects.all().order_by('creation_date') 

再後來我想要instances.latest(),但它不會給我正確的例子,實際上它給了我第一個例子。只有當我設置ORDER_BY到-creation_date或實際刪除從查詢中ORDER_BY並.latest()給我正確的實例。當我使用python manage.py shell而不是在視圖中手動測試時,也會發生這種情況。

所以,我現在所做的是在模型的元我列出order_by = ['creation_date'],而不是用在查詢中,而且作品。

我本來期望.latest()總是返回基於(日)最新的實例(時間)字段。誰能告訴我它是否是正確的,.latest()行爲異常,當你在查詢中使用order_by

回答

64

我會期待.latest()總是返回基於(日期)(時間)字段的最新實例。

documentation

如果模型的Meta指定get_latest_by,您可以在field_name參數離開關閉以latest()。 Django默認使用get_latest_by中指定的字段。

所有這一切意味着當你開火MyModel.objects.latest()時,你將得到基於日期/時間字段的最新實例。當我使用示例數據測試您的代碼時,的確如此。

然後我想要instances.latest(),但它不會給我正確的實例,實際上它給了我第一個實例。

您誤解了latest()的工作方式。當在上調用MyModel.objects時,它返回 中的最新實例。當在查詢集叫,latest將在的查詢集返回的第一個對象。您的查詢集包括由creation_date升序排列有序的MyModel所有實例。那麼這個查詢集上的latest應返回查詢集的第一個。這順便碰巧是中最古老的一行。

獲得更好理解的一種方法是查看針對latest發起的查詢。

案例1:

from django.db import connection 
MyModel.objects.latest() 
print connection.queries[-1]['sql'] 

此打印:

SELECT "app_mymodel"."id", "app_mymodel"."creation_date" FROM 
"app_mymodel" ORDER BY "app_mymodel"."creation_date" DESC LIMIT 1 

說明creation_date DESC排序和LIMIT條款。前者歸功於get_latest_by,後者歸功於latest

現在,情況2:

MyModel.objects.order_by('creation_date').latest() 
print connection.queries[-1]['sql'] 

打印

SELECT "app_mymodel"."id", "app_mymodel"."creation_date" FROM 
"app_mymodel" ORDER BY "app_mymodel"."creation_date" ASC LIMIT 1 

注意順序已更改爲creation_date ASC。這是明確的order_by的結果。 LIMIT是呃,後來有禮latest

讓我們來看看案例3:您明確指定field_nameobjects.latest()

MyModel.objects.latest('id') 
print connection.queries[-1]['sql'] 

顯示

SELECT "app_mymodel"."id", "app_mymodel"."creation_date" FROM "app_mymodel" 
ORDER BY "app_mymodel"."id" DESC LIMIT 1 
+1

非常感謝您對您出色的解釋!你已經很清楚地告訴我.latest()的工作原理以及我做錯了什麼。特別是SQL技巧是有幫助的。這在將來肯定會派上用場。 – Heyl1 2010-09-20 07:26:46

+1

如果我只想只有1個特定的最近插入的列值,該怎麼辦?假設:select「app_mymodel」。「id」FROM 「app_mymodel」ORDER BY「app_mymodel」。「creation_date」ASC LIMIT 1,什麼是等效的Python代碼? – 2015-10-19 07:29:15

7

我想這是一個已知的bug in Django 1.3發佈之後是固定的。

0

這爲我工作

latestsetuplist = SetupTemplate.objects.order_by('-creationTime')[:10][::1]