2012-11-14 44 views
2

可以說,我想匹配值的記錄,我有2種方法來做到這一點:Django的/ Python代碼:可讀VS快速的代碼

第一:

try: 
    obj = Model.objects.get(field = value) 
except 
    pass 

二:

if Model.objects.filter(field = value).count() > 0: 
    obj = Model.objects.filter(field_value)[0] 

讓我們把代碼註釋放在一邊,我應該用哪種方式或者您喜歡閱讀哪一種?第一個似乎更快,因爲只有一個數據庫查找,但第二個方式似乎更具可讀性,但需要2個數據庫查找。

+0

如果您只想要單個對象,請使用get()而不是filter() – NoPyGod

+1

[此文檔鏈接](https://docs.djangoproject.com/en/1.2/topics/db/optimization/#don-t -overuse-count-and-exists)可能是相關的。 – dokkaebi

+0

另外,你確定過濾器會拋出異常嗎?你可能不需要那個嘗試/除了。 – NoPyGod

回答

11

Python的首選是基於EAFP設計原則(「容易要求寬恕而不是權限」)。除了速度之外,這個系統的一個優點是沒有競爭條件 - 在第二個例子中,如果對數據庫的其他併發訪問在執行第一行和第二行代碼之間更改結果,那麼結果將會不一致。

根據您使用的交易,競爭條件的可能性可能是一個不是問題的問題,但在一般EAFP是Python中一個突出的設計模式和經驗豐富的Python程序員不會有任何麻煩,在形式讀取代碼。

ETA:哦,我忘了:不要用except:(你確實需要冒號)。使用except IndexError:或其他您正在尋找的特定異常。這樣,如果您遇到完全意外的錯誤,例如無法訪問數據庫,它將傳播並且不會被隱藏。你不希望出現這樣的情況,即你後來編寫的代碼計數拋出的異常意味着「沒有結果」,而是系統試圖告訴你「數據庫已關閉」。

0

如何

matches = Model.objects.filter(field=value)[:1] 
obj = matches[0] if matches else None 

查詢將只能使用一次(在條件表達式的if部分評價matches時)來評價,這是既用於空虛檢查和檢索結果。請注意切片以限制返回對象的數量。