我有一个如下的模型:
# models.py
class Lorem(models.Model):
# ...
foo_bar = models.BooleanField()
foo_baz = models.BooleanField()
# ...
该模型具有诸如foo_bar
和foo_baz
之类的字段。我知道我将来会经常查询Lorem
实例,其中foo_bar
或foo_baz
是True
。因此,我创建了一个自定义的QuerySet
,并将其添加到模型as_manager中。
# models.py
class LoremQuerySet(models.QuerySet):
def foo(self):
return self.filter(models.Q(foo_bar=True) | models.Q(foo_baz=True))
class Lorem(models.Model):
# ...
foo_bar = models.BooleanField()
foo_baz = models.BooleanField()
# ...
objects = LoremQuerySet.as_manager()
到目前为止,一切都很好。然而,在我的情况下,我可以预测我将来需要Lorem
模型上的其他字段,例如foo_boo
或foo_bee
或其他字段。每当我添加这些字段时,我都需要手动重构LoremQuerySet.foo()
以获得所有字段。
# LoremQuerySet.foo()
# ...
return self.filter(models.Q(foo_bar=True) | models.Q(foo_baz=True) | models.Q(foo_bee=True) | models.Q(foo_boo=True)) # etc
# ...
所以,我找到了一个肮脏的解决方法。I从foo_
开始过滤Lorem
的所有属性。
# LoremQuerySet.foo()
# ...
foo_attrs = filter(lambda s: s.startswith("foo_"), dir(Lorem)) # filter attrs starting with "lorem_"
# generator resulting in ("foo_bar", "foo_baz") etc
# ...
然而,我陷入了困境。如何将此筛选器与管道运算符合并?如何以编程方式将筛选的str
属性合并为Q(...) | Q(...)
?
或者,更通用地说,我如何将*args
或**kwargs
与逻辑运算符合并?
提前谢谢。
环境
- Python 3.8.5
- Django 2.2
您可以在遍历属性的同时构建Q
对象查询。
query = Q()
for attr in my_iterable:
query |= Q(attr=True)
您也可以使用&=
以类似的方式构建AND
查询
这将导致类似的结果;
<Q: (OR: ('foo_bar', True), ('foo_baz', True), ('foo_bat', True))>