web-dev-qa-db-ja.com

Django dictの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")

そして、クエリセットにテストを入れます。

これができるかどうか、そしてどのように考えますか?

14
Scentle5S

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は他のすべてを無視します。

残念ながら、ネストされた要素がオブジェクトである場合は、キー名を知っている必要があります。その場合、値によるルックアップは機能しません。

22
GwynBleidD

これには__containsルックアップを使用して、文書化されているように、クエリされた値をリストとして渡すことができるはずです ここ 。ルックアップはArrayFieldとまったく同じように動作します。したがって、次のようなものが機能するはずです。

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

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データベースの使用を検討する必要があるかもしれません。

3
DhiaTN