如何将字符串用作关键字参数?

54

我想要使用一个字符串来任意过滤ORM。我已经尝试了exec和eval的解决方案,但是遇到了困难。下面的代码不起作用,但这是我知道的最好的方法来解释我想去哪里。

from gblocks.models import Image
f = 'image__endswith="jpg"' # Would be scripted in another area, but passed as text <user input>
d = Image.objects.filter(f)


#for the non-django pythonistas:
d = Image.objects.filter(image__endswith="jpg")
# would be the non-dynamic equivalent.
3个回答

111
d = Image.objects.filter(**{'image__endswith': "jpg"})

3
你需要从关键字中分离出值,然后使用关键字作为键,值作为值来设置一个字典。然后,你可以使用双星号函数参数和字典。因此...
keyword, sep, value = f.partition('=')
kwargs = {keyword: value.strip('"')}
d = Image.objects.filter(**kwargs)

请注意,此代码假定关键字中不会出现等号“=”(它们仅用于将关键字与值分开),并且值将用引号括起来。

1
不要剥离它。改用 ast.literal_eval() - Ignacio Vazquez-Abrams
关于这个问题,如果我还想捕获datetime.date(2005,1,3)作为有效的筛选器,那么我能否使用常规的eval()函数? - Issac Kelly

1

只要将eval选项包裹在整个表达式周围,而不仅仅是f,它应该能够正常工作。

f = 'image__endswith="jpg"'
d = eval('Image.objects.filter(' + f + ')')

在用户输入上使用eval()是很危险的。如果f = "__import__('os').system('do something bad')",会怎么样呢?有关更多信息,请参见Ned Batchelder的Eval really is dangerous - wjandrea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接