简体   繁体   English

筛选Django queryset以获取dict值

[英]Filter Django queryset for a dict value

I have a queryset of Products with JSONField attributes containing dict 我有一个包含dict JSONField attributesProducts JSONField

class Product(models.Model):
attributes = JSONField(
    pgettext_lazy('Product field', 'attributes'),
    encoder=DjangoJSONEncoder, default={})

I want to filter Products where attributes['12'] == '31' 我想过滤Products ,其中attributes['12'] == '31'

Following one works: 以下一件作品:

qs.filter(attributes__contains={'12': '31'})

Following one does not: 以下一项没有:

qs.filter(attributes__12='31') Is this something I can achieve with PostgreSQL or should I move it to ES? qs.filter(attributes__12='31')这是我可以通过PostgreSQL实现的功能还是应该将其移至ES?

EDIT: Unfortunately I cannot use first solution, as this dict may contain more keys. 编辑: 不幸的是我不能使用第一个解决方案,因为此dict可能包含更多的键。

First solution works well. 第一种解决方案效果很好。 Given we have: 鉴于我们有:

product.attributes = {'333': ['6', '1']}

We can filter it out by: 我们可以通过以下方式过滤掉它:

Product.objects.filter(attributes__contains={'333': ['6']}

etc. Totally overlooked it. 等。完全忽略了它。

You should be able to use the second format, ie qs.filter(attributes__key='value') . 您应该能够使用第二种格式,即qs.filter(attributes__key='value')

Your issue in this case, as explained in the docs , is that when using an integer as a key in a JSON query, that key will be used as the index of an array, thus it's interpreted as attributes[12] instead of attributes['12'] . 本文档所述 ,您在这种情况下的问题是,当在JSON查询中使用整数作为键时,该键将用作数组的索引,因此将其解释为attributes[12]而不是attributes['12']

As long as you stick to string keys, you should be fine. 只要您坚持使用字符串键,就可以了。

An example: 一个例子:

class MyModel(models.Model)
    json = JSONField(default=dict)


p = MyModel.objects.create(json={'0': 'something', 'a': 'something else'})

MyModel.objects.filter(json__0='something') # returns empty queryset
MyModel.objects.filter(json__a='something else') # returns the object created above

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM