如何在Django JSONField中过滤JSON数组

时间:2018-03-14 10:54:54

标签: python django postgresql django-models

我对在Django 2.0.3中过滤(postgres)JSONField感到疯狂。 json存储为数组。 E.g。

tasks = [{"task":"test","level":"10"},{"task":"test 123","level":"20"}]

我尝试了什么:

myModel.objects.filter("tasks__task__contains"="test")
myModel.objects.filter("tasks_task__0__contains"="test")
myModel.objects.filter("tasks__0__task__contains"="test")
myModel.objects.filter("tasks_task__0_x__contains"="test")
myModel.objects.filter("tasks__0_x__task__contains"="test")

出了什么问题? 我想做的是一个icontains - 但正如我已经读到的那样,现在Django的jsonfields上不支持icontains ......

4 个答案:

答案 0 :(得分:1)

过滤器中的contains关键字非常强大。您可以使用以下命令从Jsonb列类型的词典数组中的任何字段中过滤出MyModel中的行。

MyModel.objects.filter(tasks__contains=["task":"test"])

这是我发现的最适合ORM的解决方案,无需区分大小写的方法。 如您所言,对于不敏感的情况,Django没有json的图标框,请使用

MyModel.objects.extra("") 为此,请在postgres中插入“ ILIKE”运算符的SQL查询。

答案 1 :(得分:1)

正确的答案应该是: myModel.objects.filter(tasks__contains = [{“ task”:“ test”}])

您可能需要添加更多过滤器以缩小并加快查询的速度,例如myModel.objects.filter(Q(tasks_level = 10,task__contains = [{“ task”:“ test”}]))

答案 2 :(得分:0)

我在这里看到两个问题。

1)Django过滤器选项用于过滤Django对象,而不是字段中的对象。您绝对可以过滤包含任务的对象" test"但您无法过滤对象中JSONField内的特定任务(您需要先检索django对象的内容,然后再执行查询)

2)据我所知django documentation on JSONFieldcontains运算符只检查字典中的键或列表中的元素。将它附加到查询查询,希望它比较我理解你的例子的值,因此不起作用。但是,可以使用contains查询字典。在您的情况下,这应该适用于查询django对象:

myModel.objects.filter("tasks__contains"={"task": "test"})

如果您只对一个字典而不是其他字典感兴趣,则需要通过以后提取正确的对象来扩展此查询:

matching_objects = myModel.objects.filter("tasks__contains"={"task": "test"})
for matching_object in matching_objects:
    for matching_task in [task for task in matching_object.tasks if "task" in task and task["task"] == "test" ]:
        print "found task", matching_task

See also this related stackoverflow answer for lookups in JSONFields with contains.

答案 3 :(得分:0)

myModel.objects.filter(tasks__contains=["task":"test"])