关于python:Django过滤器JSONField字典列表

Django filter JSONField list of dicts

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

1
2
class Test(TimeStampedModel):
    actions = JSONField()

比方说动作JSONField看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[
  {
   "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键。
当我做:

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

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

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

不是,这很有意义。我想做一些像:

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

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

并在查询集中添加测试。

任何想法是否可以做到以及如何实现?


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

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

它将列出所有Test对象,这些对象在actions字段中至少具有一个对象,该对象包含值为foo2的键fixed_key_1

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

1
2
3
4
5
6
7
Test(actions=[
    {'fixed_key_1': 'foo4', 'fixed_key_3': [
        {'key1': 'foo2'},
    ]}
}).save()

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

简单来说,包含将忽略其他所有内容。

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


您应该能够对此进行__contains查找,并将查询的值作为列表传递,如此处所述。查找的行为与ArrayField完全相同。因此,这样的事情应该起作用:

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

您可以使用django-jsonfield软件包,我想它已经是您正在使用的软件包了。

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

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

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

如果使用的是PostgreSQL,也许您可??以利用PostgreSQL特定的模型字段。

PS:如果要处理大量JSON结构,则可能要考虑使用NoSQL数据库。