轉載自http://www.360doc.com/content/18/0731/18/58287567_774731201.shtml
django提供的數據庫操作API中的distinct()函數,了解SQL語句的讀者都應該知道,DISTINCT關鍵字可以在select操作時去重。django里的這個distinct()函數也是這個功能,通常的用法是我們要取出一張表中的某一列的所有值,並且只取出不重復的,如果有重復的就只取出來一次,網絡上幾乎所有的對這個函數的使用例子對應的Python代碼都如下:
但是這樣的用法往往達不到使用者的意圖,可以來看一下網絡上流傳甚廣的一個問答:
比如這個:http://bbs.csdn.net/topics/330006477
再比如這個:http://www.douban.com/group/topic/17856879/
這里其實說的都是一個例子,仔細看這個解答
—– 需要注意的是,這樣返回的是一個字典的列表,而不是通常的 QuerySet — 這樣是過濾不掉的,這是個問題,還是有5個對象在里面,對結果使用len(obj)就知道沒有任何變化,但是如果只作統計不重復數據的個數的話,還是准確的3個 obj=ClassName.objects.values(‘name’).distinct() len(obj)=5 obj.count()=3 但是結果集中沒有起到任何的過濾作用,此問題有待解決!!!!!
有理有據,讓人很信服的認為distinct()函數沒有實現其所描述的功能。真的是這樣么?
在這里負責的告訴讀者,上面的解釋是錯誤的,distinct()具有去重功能是沒有必要懷疑的,那為什么會出現上面的解釋呢?因為他不知道distinct()函數有一個隱藏特性,當使用distinct()函數的時候,如果不使用order_by()函數做跟隨,那么該函數會自動把當前表中的默認排序字段作為DISTINCT的一個列,所以上述問題出現的原因是因為他沒有使用order_by(‘name’)來屏蔽distinct()的那個特性,從而得出的distinct結果並不是僅僅以name一個列作為參數的,而是以id+name兩列的值作為distinct參數,可以看到id列里面的值全部都是唯一值,所以得出來的結果必然是以id列的值為標准的,這也就是的原因,而如果想要實現上述例子中樓主的需求,正確的代碼寫法是:
Python
d1 = models.Device.objects.values('business_id').distinct().order_by('business_id')
在1.4+版本的django中distinct()函數可以傳入一個參數,從而省去了后面跟加一個order_by()函數的必要,但是這也需要你的數據庫支持Postgresql,否則還是無效的。