我正在尝试查找动态查询的最佳方式。该项目的 前端将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
我认为你在这里重新发明轮子。你可能想要调查像GraphQL这样的东西。 –