Django过滤JSONField dicts列表

时间:2015-12-18 14:52:28

标签: python django django-models django-queryset django-jsonfield

我使用新的JSONField运行Django 1.9并拥有以下测试模型:

class Test(TimeStampedModel):
    actions = JSONField()

让我们说JSONField的动作如下:

[
  {
    "fixed_key_1": "foo1",
    "fixed_key_2": {
      "random_key_1": "bar1",
      "random_key_2": "bar2",
    }
  },
  {
    "fixed_key_1": "foo2",
    "fixed_key_2": {
      "random_key_3": "bar2",
      "random_key_4": "bar3",
    }
  }
]

我希望能够为列表中的每个项目过滤foo1和foo2键。 当我这样做时:

>>> Test.objects.filter(actions__1__fixed_key_1="foo2")

测试位于查询集中。但是当我这样做时:

>>> Test.objects.filter(actions__0__fixed_key_1="foo2")

不是,这是有道理的。我想做点什么:

>>> Test.objects.filter(actions__values__fixed_key_1="foo2")

或者

>>> Test.objects.filter(actions__values__fixed_key_2__values__contains="bar3")

在查询集中进行测试。

知道是否可以这样做以及如何做?

3 个答案:

答案 0 :(得分:18)

如果您不想按照数组中的某个字段过滤数据,可以尝试以下查询:

deflate

它将列出Test.objects.filter(actions__contains=[{'fixed_key_1': 'foo2'}]) 字段中至少包含一个对象的Test个对象,其中包含值为actions的键fixed_key_1

即使您不知道实际索引,它也应该适用于嵌套查找:

foo2

简单来说,contains会忽略其他所有内容。

不幸的是,如果嵌套元素是一个对象,则必须知道密钥名称。在这种情况下,按值查找将不起作用。

答案 1 :(得分:3)

你可以使用django-jsonfield包,我猜它已经是你正在使用的包。

from jsonfield import JSONField
class Test(TimeStampedModel):
    actions = JSONField()

因此,要搜索使用特定属性进行搜索,您可以执行以下操作:

def test_filter(**kwargs):
    result = Test.objects.filter(actions__contains=kwargs)
    return result

如果你正在使用PostgreSQL,也许你可以利用PostgreSQL specific model fields

PS:如果你正在处理很多JSON结构,你可能会考虑使用NoSQL数据库。

答案 2 :(得分:3)

您应该可以对此使用__contains查找,并将查询后的值作为已记录here的列表传递。查找的行为与ArrayField完全相同。所以,这样的事情应该有效:

Test.objects.filter(actions__contains=[{'fixed_key_1': 'foo2'}])