2009-07-29 240 views
0

我試圖找出Django模型中是否存在元素。我認爲這應該很容易做到,但在Django文檔的Making queries部分找不到任何優雅的方式。檢查一個元素是否存在

我現在的問題是,我在一個目錄中有成千上萬的屏幕截圖,需要檢查它們是否在應該存儲它們的數據庫中。所以我正在遍歷文件名,並希望看到他們每個人是否存在相應的元素。有一個叫做屏幕截圖的模型,我能想到的唯一方法是

filenames = os.listdir(settings.SCREENSHOTS_ON_DISC) 
for filename in filenames: 
    exists = Screenshot.objects.filter(filename=filename) 
    if exists: 
     ... 

有沒有更好/更快的方法來做到這一點?請注意,截圖可以在數據庫中多次(因此我沒有使用.get)。

回答

2

如果您的Screenshot模型具有很多屬性,那麼您顯示的代碼爲您的特定需求做了不必要的工作。例如,你可以這樣做:

files_in_db = Screenshot.objects.values_list('filename', flat=True).distinct() 

,這將給你數據庫中的所有文件名列表,並生成SQL只獲取文件名。它不會嘗試創建並填充屏幕截圖對象。如果你有

files_on_disc = os.listdir(settings.SCREENSHOTS_ON_DISC) 

,那麼你可以在一個列表迭代中的其他找會員,或使一個或兩個列表成爲集來找到共同的成員等

1

你可以嘗試:

Screenshot.objects.filter(filename__in = filenames) 

這將會給你所有你確實有截圖的列表。你可以比較兩個列表,看看兩者之間不存在什麼。這應該讓你開始,但你可能想調整查詢的性能/使用。

1

此查詢獲取你的所有文件在您的數據庫和文件系統中:

discfiles = os.listdir(settings.SCREENSHOTS_ON_DISC) 

filenames = (Screenshot.objects.filter(filename__in=discfiles) 
           .values_list('filename', flat=True) 
           .order_by('filename') 
           .distinct()) 

注意order_by。如果您在模型定義中指定了排序,則使用distinct可能不會返回您所期望的。這是記錄在這裏:

所以做出明確的排序,然後執行查詢。