2017-09-04 72 views
1

我正在嘗試查找動態查詢的最佳方式。該項目的 前端將JSON發送到後端與查詢獲取對象的查詢通過參數:動態地進行查詢

Model.objects.filter(**query) 

我可以在我的願望設置JSON格式。在這一刻JSON:

# first case 
{'type': 'channel_type', 'or': {'param1': {'__gte': 10}, 'param2': {'': 12}}} 
# second case 
{'type': {'in': ['channel1', 'channel2']}, 'and': {'p1': {'__lte': 12}, 'p2': {'!=': 1}}} 

這將是SQL等於(選擇Y X - 是靜態的,代碼只生成 '其中' 條件):

# first case 
WHERE table.type = channel_type AND (table.param1 >= 10 OR table.param2 = 12 
# second case 
WHERE table.type IN [channel1, channel2] AND (table.p1 <= 12 AND table.p2 <> 1) 

我已經做到了:

query_params_dict = {'>': '__gt', '<': '__lt', '>=': '__gte', '<=': '__lte', '==': ''} 

def parse_segmentation_query(query): 
    type = {'type': query.pop('type')} if isinstance(query['type'], str) else {'type__in': query.pop('type')['in']} 
    query = recursive_parsing_query(query) 
    query.update(type) 
    return query 

Func「recursive_parsing_query」未準備好,所以沒有顯示。 但我想遞歸地從字典中彈出params,並使{{param1__gte':2}字典將在** kwards中傳遞給objects.filter。 問題是越來越「不等於」條件=>它打破簡寫「Model.objects.filter(**查詢),因爲那裏我們需要」排除「。

我想知道:這種方式是最好的對於動態進行查詢或者你也可以提供更好,如果沒有,所以我怎麼能傳遞排除只有過濾條件

UPD:???肯定JSON查詢 會更深

UPDATE:

最後,我這樣做(動態查詢通過數字字段進行過濾),感謝MJafar Mash:

condition_types = {'>': '__gt', '<': '__lt', '>=': '__gte', '<=': '__lte', '==': '', '!=': ''} 
q_conditions = {'or': True, 'and': False} 


def recursive_parsing_query(query, or_condition=False): 
    filter_obj = Q() 
    for key, value in query.items(): 
     if key in q_conditions: 
      local_filter = recursive_parsing_query(value, q_conditions[key]) 
     else: 
      local_filter = simple_parsing_query(key, value) 
     if or_condition: 
      filter_obj |= local_filter 
     else: 
      filter_obj &= local_filter 
    return filter_obj 


def simple_parsing_query(parameter_name, parameter_query): 
    local_filter = Q() 
    for condition_type, condition_value in parameter_query.items(): 
     parameter_condition = {parameter_name + condition_types[condition_type]: condition_value} 
     if condition_type != '!=': 
      local_filter = Q(**parameter_condition) 
     else: 
      local_filter = ~Q(**parameter_condition) 
    return local_filter 
+1

我認爲你在這裏重新發明輪子。你可能想要調查像GraphQL這樣的東西。 –

回答

2

的方式filterexcludeinternally implemented的啓發,我建議重寫查詢生成算法使用Qobjects話,我想你不會有否定或查詢生成的遞歸岬任何問題算法。

+0

謝謝,你現在可以看到問題身體的功能。 –

+0

@JeffersonH​​oup酷!很高興有幫助。 –