2013-07-12 56 views
2

我有一個有很多字段的模型。我想構建一個查詢集,從預定義的字段列表中選擇具有空白字段的對象。 (任何領域,不是所有的)Django,自動構建長查詢集

說:

fields=['a','b','c','d','e','f','g','h','i','j','k'] 

我可以寫

model.objects.filter(Q(a==Null) | Q(b==Null) | Q(c==Null) ... 

有沒有更好的辦法?

回答

2

這個怎麼樣?

qObj = None 
for field in fields: 
    newQ = Q(**{field : Null}) 
    if qObj is None: 
     qObj = newQ 
    else: 
     qObj = qObj | newQ 

我不愛qObj = None和下面的檢查,但建立Q對象時,我不知道的辦法解決它。但是,Q(**{field: Null})可能是您一般需要的。

+0

非常簡單的方法,謝謝! – wjdp

0

漂亮的混淆(加reduce()lambda正在BDFL甚至批評),但應該工作:

from django.db.models import Q 
q_result = reduce(lambda q, name: q | Q(**{name: None}), fields, Q()) 

然後,只需使用它:

model.objects.filter(q_result) 
1

我想這應該這樣做:

query_terms = {} 
for fieldname in fields: 
    query_terms['%s__isnull' % fieldname] = False 
model.objects.exclude(**query_terms) 

或者,如果你是在2.7或更高版本,使用字典理解到BUI ld query_terms

您最初的查詢很尷尬,因爲它需要or'd在一起 - 如果您排除否定,您可以使用隱式和。

+1

這是另一種(可能很好)的方法:排除所有沒有'NULL'字段的結果。 – Tadeck

+0

也是一個很好的直接的方法,我會盡力看看最好的效果 – wjdp

0

您可能想重新考慮表格的設計方式。即使您成功找到解決方案,您也會遇到性能問題。

如果您使用的是PostgreSQL,它會附帶HStore。

此鏈接將幫助您開始,Working with the hstore data type in PostgreSQL 9.0/9.1/9.2和此庫供Django使用hstore,PostgreSQL HStore module integration for django orm

Hstore是一個關鍵值存儲區,您只能存儲具有值的字段。

+0

我沒有處理大量的記錄,所以不應該是一個問題。可能值得添加一個布爾字段,根據特定字段的狀態保存更新。 – wjdp

+0

可能是,我提供的解決方案是另一種選擇,當事情變得有點毛茸茸的時候。你可能永遠不知道什麼時候需要它。 – rendykstan