2013-08-06 74 views
1

我有一個列表,我想過濾我的Queryset,當這些項目中的任何一個被發現在一個外部表的非主鍵「測試」。所以我寫這樣的東西:Django Queryset過濾器缺少行情

test_list = ['test1', 'test2', 'test3', 'test4', 'test5'] 
return cls.objects.filter(reduce(lambda x, y: x | y, [models.Q(next_task__test = item) for item in test_list]))[:20] 

這將返回一個空的列表。當我看它生成的SQL查詢,我得到:

SELECT ... 
FROM ... 
WHERE "job"."next_task_id" IN (test1, test2, test3, test4, test5) LIMIT 20; 

而它本來應該是這樣的:

SELECT ... 
FROM ... 
WHERE "job"."next_task_id" IN ('test1', 'test2', 'test3', 'test4', 'test5') LIMIT 20; 

不帶引號,SQLite3的認爲那些是列名,並且不回報什麼。當我手動添加引號並在沒有Django的表上執行SQLite3查詢時,我會得到期望的結果。我如何讓Django正確地發出查詢?

+1

試試'str(item)' – keyser

+4

爲什麼不使用:'cls.objects.filter(next_task__test__in = test_list)'? –

+0

放入'in'不會改變任何內容。把'exact'放在'OR's鏈中,但是缺少的引號仍然缺失。類型轉換沒有效果。 –

回答

1

這個問題很有意思,它似乎只發生在SQLite中。它在這裏是已知的:https://code.djangoproject.com/ticket/14091docs

所以基本上查詢可能不會是錯的,但是當你查詢回來的Django看起來錯誤:

>>> test_list = ['test1', 'test2', 'test3', 'test4', 'test5'] 
>>> cls.objects.filter(next_task__test__in=test_list).query.__str__() 

SELECT ... 
FROM ... 
WHERE "job"."next_task_id" IN (test1, test2, test3, test4, test5); 

解決方法:如果你真的想查詢是錯誤的,然後提供更多報價該名單,如:

>>> test_list = ["'test1'", "'test2'", "'test3'", "'test4'", "'test5'"] 
>>> cls.objects.filter(next_task__test__in=test_list).query.__str__() 

SELECT ... 
FROM ... 
WHERE "job"."next_task_id" IN ('test1', 'test2', 'test3', 'test4', 'test5'); 

無論如何,我會依靠標準的一個,上面的工作太hackish。

+0

該文件說查詢可能無法正確打印到控制檯,這很好,但Django返回列表與這個查詢空列表,當我添加引號並在SQLite3手動運行,我得到我想要的結果。所以這個查詢不僅被打印錯誤,而且它也以某種方式被錯誤地運行。 –

+0

所以如果你在上面的工作中添加更多的引用到'test_list',它是否工作?我仍然認爲這個問題是別的。 –