问题
I run Django 1.9 with the new JSONField and have the following Test model :
class Test(TimeStampedModel):
actions = JSONField()
Let's say the action JSONField looks like this :
[
{
"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",
}
}
]
I want to be able to filter the foo1 and foo2 keys for every item of the list. When I do :
>>> Test.objects.filter(actions__1__fixed_key_1="foo2")
The Test is in the queryset. But when I do :
>>> Test.objects.filter(actions__0__fixed_key_1="foo2")
It isn't, which makes sense. I want to do something like :
>>> Test.objects.filter(actions__values__fixed_key_1="foo2")
Or
>>> Test.objects.filter(actions__values__fixed_key_2__values__contains="bar3")
And have the Test in the queryset.
Any idea if this can be done and how ?
回答1:
If you wan't to filter your data by one of fields in your array of dicts, you can try this query:
Test.objects.filter(actions__contains=[{'fixed_key_1': 'foo2'}])
It will list all Test
objects that have at least one object in actions
field that contains key fixed_key_1
of value foo2
.
Also it should work for nested lookup, even if you don't know actual indexes:
Test(actions=[
{'fixed_key_1': 'foo4', 'fixed_key_3': [
{'key1': 'foo2'},
]}
}).save()
Test.objects.filter(actions__contains=[{'fixed_key_3': [{'key1': 'foo2'}]}])
In simple words, contains will ignore everything else.
Unfortunately, if nested element is an object, you must know key name. Lookup by value won't work in that case.
回答2:
You can use the django-jsonfield package, I guess it's already the one you are using.
from jsonfield import JSONField
class Test(TimeStampedModel):
actions = JSONField()
So to search to make a search with a specific property, you can just do this:
def test_filter(**kwargs):
result = Test.objects.filter(actions__contains=kwargs)
return result
If you are using PostgreSQL, maybe you can take advantage of PostgreSQL specific model fields.
PS: If you are dealing with a lot of JSON structure you have maybe to consider using NoSQL Database.
回答3:
You should be able to use a __contains
lookup for this and pass queried values as list as documented here. The lookup would behave exactly like ArrayField. So, something like this should work:
Test.objects.filter(actions__contains=[{'fixed_key_1': 'foo2'}])
来源:https://stackoverflow.com/questions/34358278/django-filter-jsonfield-list-of-dicts