首页 > 解决方案 > 检查 is_null 以获取 Django 查询集过滤中的字段列表

问题描述

我已经使用以下字段创建模型:

field_1 , field_2, field_3, ... , field_n

我想要filter这些 k 字段的所有对象:

field_1 , field_2, .... , field_k

这些对象不是Null

我的错误答案:

我确实认为我必须创建要在查询中设置的字段列表:

my_list = [`field_1` , `field_2`, .... , `field_k`]

并像这样创建我的查询:

my_objects = Class.objects.filter([ (eval(field_name +"__isnull = False") )  for field_name in my_list ])

但这是错误的。我怎样才能做到这一点?

标签: pythondjangodjango-modelsdjango-queryset

解决方案


你把事情弄得太复杂了,你不能用字符串构造一个列表并将它传递给filter(..)希望它能起作用。此外eval(..),这种方式不起作用,即使这样做,也会导致严重的安全风险。eval(..)并且exec(..)应该尽可能避免,因为从有人设法将字符串“注入”到其中的那一刻起,他们就可以在您的服务器上运行任意代码,从而尝试“转储数据库”等。请参阅此答案以获取更深入的分析为什么“ Eval is bad practice ”。

您可以构造一个字段名称列表(如字符串):

my_list = ['field_1', 'field_2', 'field_k']

然后我们可以构造一个字典并执行字典解包,例如:

Class.objects.filter(**{'{}__isnull'.format(f): False for f in my_list})

因此,两个星号 ( **) 将进行函数调用,使得f(**{'a': 4, 'b': 2}), 与 相同f(a=4, b=2),因此在这里它将进行类似的调用.filter(field_1__isnull=False, field_2__isnull=False, field_k__isnull=False)

或者从开始,我们可以使用f-strings

Class.objects.filter(**{f'{f}__isnull': False for f in my_list})

推荐阅读