如何将**kwargs与管道操作符合并



我有一个如下的模型:

# models.py
class Lorem(models.Model):
# ...
foo_bar = models.BooleanField()
foo_baz = models.BooleanField()
# ...

该模型具有诸如foo_barfoo_baz之类的字段。我知道我将来会经常查询Lorem实例,其中foo_barfoo_bazTrue。因此,我创建了一个自定义的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_boofoo_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
# ...

所以,我找到了一个肮脏的解决方法。Ifoo_开始过滤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))>

最新更新