Django过滤器JSONField命令列表

时间:2022-12-22 01:34:24

I run Django 1.9 with the new JSONField and have the following Test model :

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

class Test(TimeStampedModel):
    actions = JSONField()

Let's say the action JSONField looks like this :

假设动作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",
    }
  }
]

I want to be able to filter the foo1 and foo2 keys for every item of the list. When I do :

我希望能够为列表中的每一项过滤foo1和foo2键。当我做:

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

The Test is in the queryset. But when I do :

测试在queryset中。但当我这么做的时候:

>>> 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.

并在queryset中进行测试。

Any idea if this can be done and how ?

你知道这能不能实现吗?

3 个解决方案

#1


17  

If you wan't to filter your data by one of fields in your array of dicts, you can try this query:

如果您不想通过dicts数组中的一个字段来过滤您的数据,您可以尝试以下查询:

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.

它将列出所有在actions字段中至少有一个对象的测试对象,这些对象包含value foo2的key fixed_key_1。

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.

简单来说,contains将忽略其他所有东西。

Unfortunately, if nested element is an object, you must know key name. Lookup by value won't work in that case.

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

#2


2  

You should be able to use a __contains lookup for this, as documented here. The lookup would still be like what DhiaTN recommended above. So, something like this should work:

您应该能够为此使用__contains查找,如本文所述。查找仍然与DhiaTN推荐的类似。所以,像这样的东西应该是有用的:

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

#3


2  

You can use the django-jsonfield package, I guess it's already the one you are using.

你可以使用django-jsonfield包,我猜它已经是你正在使用的包了。

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.

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

PS: If you are dealing with a lot of JSON structure you have maybe to consider using NoSQL Database.

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

#1


17  

If you wan't to filter your data by one of fields in your array of dicts, you can try this query:

如果您不想通过dicts数组中的一个字段来过滤您的数据,您可以尝试以下查询:

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.

它将列出所有在actions字段中至少有一个对象的测试对象,这些对象包含value foo2的key fixed_key_1。

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.

简单来说,contains将忽略其他所有东西。

Unfortunately, if nested element is an object, you must know key name. Lookup by value won't work in that case.

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

#2


2  

You should be able to use a __contains lookup for this, as documented here. The lookup would still be like what DhiaTN recommended above. So, something like this should work:

您应该能够为此使用__contains查找,如本文所述。查找仍然与DhiaTN推荐的类似。所以,像这样的东西应该是有用的:

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

#3


2  

You can use the django-jsonfield package, I guess it's already the one you are using.

你可以使用django-jsonfield包,我猜它已经是你正在使用的包了。

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.

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

PS: If you are dealing with a lot of JSON structure you have maybe to consider using NoSQL Database.

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