过滤 Django 查询集以获取 dict 值

Posted

技术标签:

【中文标题】过滤 Django 查询集以获取 dict 值【英文标题】:Filter Django queryset for a dict value 【发布时间】:2018-05-12 11:17:24 【问题描述】:

我有一个 Products 的查询集 JSONField attributes 包含 dict

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

我想过滤Products,其中attributes['12'] == '31'

以下作品:

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

以下没有:

qs.filter(attributes__12='31') 这是我可以通过PostgreSQL 实现的目标,还是应该将其移至 ES?

编辑: 不幸的是我不能使用第一个解决方案,因为这个dict 可能包含更多的键。

第一个解决方案效果很好。鉴于我们有:

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

我们可以通过以下方式过滤掉它:

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

等等。完全忽略了它。

【问题讨论】:

根据this question,Postgres 确实支持它,但我不确定 Django 是否/如何实现这一点。 【参考方案1】:

您应该可以使用第二种格式,即qs.filter(attributes__key='value')

在这种情况下,您的问题是 explained in the docs,当在 JSON 查询中使用整数作为键时,该键将用作数组的索引,因此它被解释为 attributes[12] 而不是 @ 987654324@.

只要你坚持使用字符串键,你应该没问题。

一个例子:

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

【讨论】:

以上是关于过滤 Django 查询集以获取 dict 值的主要内容,如果未能解决你的问题,请参考以下文章

修改列表视图查询集以汇总包含具有相同值的列的表

如何链接 Django 查询集以保留单个顺序

Django如何获取0而不是null

Django:保存旧的查询集以供将来比较

如何按非字段值过滤 Django 查询集

子查询 django 查询以从对象中获取最大的不同值并返回这些对象