9

のJSONFieldリストをフィルタリング:Djangoは、私は新しいJSONFieldとDjangoの1.9を実行して、次のテストモデルを持っているdicts

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") 

そしてクエリセットでテストを持っている:私のような何かをしたいです。

どうすればいいですか?

答えて

2

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データベースの使用を検討することをお勧めします。

+1

私は実際にPostgreSQLのJSONField固有モデルフィールド( 'django.contrib.postgres.fields import JSONField')を既に使用しています。あなたの解決策は 'your_property'がわかっているとき(私の場合は' fixed_key_1'と 'fixed_key_2')に動作しますが、' your_property'(私の場合は 'random_key_#')を知らないとどうしたらいいですか? – Scentle5S

+0

'{'fixed_key_1': 'foo2'}'をあなたのパラメタにして、コードをジェネリック関数で更新しました。 – DhiaTN

+1

私は、特にあなたの 'your_property'を知らないのです。それは何でもかまいませんし、気にしなくても、深さに関係なくJSONFieldに任意の値の文字列が含まれているかどうかを知りたいだけです。 – Scentle5S

2

ルックアップを使用してください(hereを参照)。ルックアップは、DhiaTNが上記で推奨したものと同じである。だから、このようなものが動作するはずです:

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

あなたがdictsのあなたの配列内のフィールドのいずれかで、あなたのデータをフィルタリングするwan't場合は、このクエリを試すことができます。

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

それが一覧表示されますすべてTest のキーfixed_key_1を含むactionsフィールドに少なくとも1つのオブジェクトを持つオブジェクト。

また、それはあなたが実際にインデックスを知らない場合でも、ネストされた検索のために働く必要があります。

Test(actions=[ 
    {'fixed_key_1': 'foo4', 'fixed_key_3': [ 
     {'key1': 'foo2'}, 
    ]} 
}).save() 

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

を簡単な言葉では、他のすべてを無視しますが含まれています。

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

関連する問題