我有一个列表,当在外部表的非主键“测试”中找到这些项目时,我想过滤我的查询集。所以我写了这样的东西:
test_list = ['test1', 'test2', 'test3', 'test4', 'test5']
return cls.objects.filter(reduce(lambda x, y: x | y, [models.Q(next_task__test = item) for item in test_list]))[:20]
这将返回一个空列表。当我查看它生成的 SQL 查询时,我得到:
SELECT ...
FROM ...
WHERE "job"."next_task_id" IN (test1, test2, test3, test4, test5) LIMIT 20;
而它本来应该是这样的:
SELECT ...
FROM ...
WHERE "job"."next_task_id" IN ('test1', 'test2', 'test3', 'test4', 'test5') LIMIT 20;
如果没有引号,SQLite3 认为这些是列名,并且不返回任何内容。当我手动添加引号并在完全没有 Django 的情况下在表上执行 SQLite3 查询时,我得到了想要的结果。如何让 Django 正确发出查询?
请您参考如下方法:
这个问题很有意思,好像只有SQLite才会出现。在这里已知:https://code.djangoproject.com/ticket/14091在docs .
所以基本上查询可能没有错,但是当你用 Django 返回查询时它看起来是错误的:
>>> test_list = ['test1', 'test2', 'test3', 'test4', 'test5']
>>> cls.objects.filter(next_task__test__in=test_list).query.__str__()
SELECT ...
FROM ...
WHERE "job"."next_task_id" IN (test1, test2, test3, test4, test5);
解决方法:如果您真的认为查询有误,请为列表提供更多报价,例如:
>>> test_list = ["'test1'", "'test2'", "'test3'", "'test4'", "'test5'"]
>>> cls.objects.filter(next_task__test__in=test_list).query.__str__()
SELECT ...
FROM ...
WHERE "job"."next_task_id" IN ('test1', 'test2', 'test3', 'test4', 'test5');
无论如何我都会依赖标准的,上面的解决方法太老套了。
