新しい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")
そして、クエリセットにテストを入れます。
これができるかどうか、そしてどのように考えますか?
Dictの配列のフィールドの1つでデータをフィルタリングしたくない場合は、次のクエリを試すことができます。
Test.objects.filter(actions__contains=[{'fixed_key_1': 'foo2'}])
値fixed_key_1
のキーfoo2
を含むTest
フィールドに少なくとも1つのオブジェクトがあるすべてのactions
オブジェクトが一覧表示されます。
また、実際のインデックスがわからない場合でも、ネストされたルックアップで機能するはずです。
Test(actions=[
{'fixed_key_1': 'foo4', 'fixed_key_3': [
{'key1': 'foo2'},
]}
}).save()
Test.objects.filter(actions__contains=[{'fixed_key_3': [{'key1': 'foo2'}]}])
簡単に言うと、containsは他のすべてを無視します。
残念ながら、ネストされた要素がオブジェクトである場合は、キー名を知っている必要があります。その場合、値によるルックアップは機能しません。
これには__contains
ルックアップを使用して、文書化されているように、クエリされた値をリストとして渡すことができるはずです ここ 。ルックアップはArrayFieldとまったく同じように動作します。したがって、次のようなものが機能するはずです。
Test.objects.filter(actions__contains=[{'fixed_key_1': 'foo2'}])
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 特定のモデルフィールド を利用できる可能性があります。
PS:多くのJSON構造を扱っている場合は、NoSQLデータベースの使用を検討する必要があるかもしれません。