2014-07-01 249 views
0

我試圖通過檢查對象是否在這些對象的列表中來過濾查詢集。Django按模型對象列表過濾

employee_list = [<Employee: A>, <Employee: B>, <Employee: C>] 
qs = Employee.objects.filter(id__in=employee_list, [other_filters]) 

在上面運行之後,qs是一個空列表。我在想,我可以做一個新的列表,如

employee_ids = [emp.id for emp in employee_list] 
qs = Employee.objects.filter(id__in=employee_ids, [other_filters]) 

我沒有做過標杆這種方法,但我想可能性能會受到打擊。或者,我可以在之後交叉清單,例如:

qs = Employee.objects.filter([other_filters]) 
filtered_qs = [emp for emp in employee_lids if emp in qs] 

但是,我認爲這樣的表現會更糟糕。

什麼是最好的/最快的方式來做到這一點?謝謝。

回答

1

正如Martol1ni注意到你想在SQL級別儘可能所以我覺得你的方法也得到越來越慢過濾,但另一個問題...

基於Django的文檔:https://docs.djangoproject.com/en/dev/ref/models/querysets/我覺得你id__in應該是整數ID的列表,而不是模型列表。

編輯︰ 哦,我看他在他的答案中涵蓋了這一點,但它並沒有明確表示它是不正確的在你的問題。

EDIT2: 但是,是的,如果你想知道肯定,真正重要的是現實世界中的表現,你可以用django-debug-toolbar做。在我看來,雖然真正的問題是id__in誤用,導致你找到更復雜的方式來做你想做的事情。

+0

我對每種不同的方法都運行了一個分析器,但沒有看到它們之間的太多差別。我的測試數據集顯然比生產要小,但是從對象列表中構建一個id列表,然後在id_list中過濾id__似乎是最快的。 – SirDeimos

0

的經驗法則是通過SQL儘可能過濾,所以我會去

qs = Employee.objects.filter(id__in=[emp.id for emp in employee_list], [other_filters]) 

我沒有任何性能測試與雖然支持這一行動。

+2

我可能會注意到這很大程度上取決於查詢集,列表和用例的大小 – Alvaro

+0

因此沒有性能測試來備份它。 – Martol1ni