【问题标题】:Check is_null for list of field in Django queryset filtering检查 is_null 以获取 Django 查询集过滤中的字段列表
【发布时间】:2019-11-13 16:41:34
【问题描述】:

我已经用这个字段创建了模型:

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 ])

但这是错误的。 我该怎么做?

【问题讨论】:

    标签: python django django-models django-queryset


    【解决方案1】:

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

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

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

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

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

    两个星号 (**) 将因此进行函数调用,使得 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(**{<b>f'{f}__isnull'</b>: False for f in my_list})

    【讨论】:

    • 感谢您的精彩回答!我对eval 有疑问:如果我没有从用户那里得到传递给eval 函数的值并自己填写,是否还有安全问题? @willem-van-onsem
    • @Whale52Hz:这是一个功能,恕我直言,只能来自地狱:)。它简直不优雅,几乎你用它做的所有事情都可以用比 eval 更好的方式完成,它效率低下,而且它是“复杂的”,因为将变量传递给 eval 可能通常比一个更难期望:)。
    • :) 不错。好,谢谢。我试着忘记python有这样的功能:) @willem-van-onsem
    猜你喜欢
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 2016-07-20
    相关资源
    最近更新 更多