Django查询带可变数量的过滤参数

5 投票
4 回答
2880 浏览
提问于 2025-04-18 07:04

我有一个Django查询,它根据某些条件从MyModel中获取数据:

if beta:
    MyModel.object.filter(x=alpha, y=beta)
else:
    MyModel.object.filter(x=alpha)

有没有办法去掉if beta:这个检查,直接用一行代码来实现,也就是说只有在beta不为None的时候,查询才会根据y进行过滤?

这样做算不算一个好的(Django风格的)方法:

MyModel.object.filter(**{'x':alpha, 'b':beta} if beta else **{'x':alpha})

或者有没有可能像这样做(我知道下面的写法是错的,但能不能修正一下,让它表达正确的意思?):

MyModel.object.filter(Q('x'=alpha) & (beta && Q('y'=beta)))

4 个回答

0

我会使用

objects = MyObject.objects.filter(x=alpha)
if beta:
    # Additional filter because of ...
    objects = objects.filter(y=beta)

你的写法看起来就是不太容易读懂。Python 语言的设计初衷就是要让代码更容易阅读。需要注意的是,这种写法只适合简单的筛选(没有多值关系),正如 buffer 提到的那样。否则,我觉得你最开始的写法看起来更好。

1

一种实现这个功能的方法是使用 Q 对象,可以参考 这个回答

在你的情况下:

query = Q(x=alpha)
if beta:
    query = query & Q(y=beta)
MyModel.object.filter(query)

虽然没有比其他例子更简短,但如果你添加更多变量来测试,代码会更清晰。

希望对你有帮助,

8

在这种情况下,我通常会使用下面的解决方案:

filter_kwargs = {'x': alpha}
if beta:
    filter_kwargs['y'] = beta

 MyModel.objects.filter(**filter_kwargs)

这样做很容易在项目需求中添加新的条件,但不幸的是,这不是一个简单的一行代码就能解决的问题。

撰写回答