關於Django中的數據庫操作API之distinct去重的一個誤傳


轉載自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,否則還是無效的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM