Django:按值过滤或返回所有记录

我有以下代码(django,python):


def function(self, some_id):

    if some_id:

        return Model1.objects.filter(model2__id=some_id)

    else:

        return Model1.objects.all()

我想知道是否可以使用单个return语句来重构此代码?Model1在Model2.id上具有外键。


小唯快跑啊
浏览 284回答 2
2回答

蛊毒传说

def function(self, some_id):    filter_kwargs = {}    if some_id:        filter_kwargs['model2__id'] = some_id    return Model1.objects.filter(**filter_kwargs)应该可以满足您的问题,尽管我会说书面形式最有可能。

子衿沉夜

好吧,您可以像这样解决此问题: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}    )
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python