2 回答
TA贡献1895条经验 获得超3个赞
def function(self, some_id):
filter_kwargs = {}
if some_id:
filter_kwargs['model2__id'] = some_id
return Model1.objects.filter(**filter_kwargs)
应该可以满足您的问题,尽管我会说书面形式最有可能。
TA贡献1828条经验 获得超3个赞
好吧,您可以像这样解决此问题:
def function(self, some_id):
return Model1.objects.filter(*(some_id and [Q(model2__id=some_id)] or []))
但这是很神秘的。
我个人很喜欢实现一个filter_not_none,它只是过滤掉带有Noneas值的语句,例如:
def filter_not_none(qs, **kwargs):
return qs.filter(**{k: v for k, v in kwargs.item() if v is not None})
然后我们可以简单地使用:
def function(self, some_id):
return filter_not_none(Model1.objects, model2__id=some_id)
这适用于任意数量的命名参数。因此不是位置参数或Q对象。
这是有效的,因为filter(..)没有参数的a不会过滤任何内容。我们使用字典理解,从而检查哪个kwargs具有非None值,并且仅将它们传递给.filter(..)调用。
然后,您可以使用例如:
return filter_not_none(
Model.objects,
name=some_name,
date__lt=some_date
)
如果some_name是None,我们做的名字没有过滤器,如果some_date是None我们没有过滤器时date__lt,如果两者都是None,我们不会过滤所有,并且如果两者都没有 None,我们过滤器上都。
我们可以对其进行扩展以使其也可以与Q对象一起使用*args,但是检查这些-Q对象和表达式将非常困难,并且还可能导致各种不良行为。但是,也需要Q对象的扩展是:
def filter_not_none(qs, *args, **kwargs):
# warning, does not perform manipulations on Q-objects, Q-expressions
# and unnamed parameters in general
return qs.filter(
*args,
**{k: v for k, v in kwargs.item() if v is not None}
)
添加回答
举报