15

我需要对 django 1.10 中的 postgres 支持的 jsonfield 上的嵌套键进行 values/values_list 查询,例如。

class AbcModel(models.model):
    context = fields.JSONField()

如果它具有以下值:

{
  'lev1': {
    'lev': 2
  }
}

我想运行类似的查询

AbcModel.objects.values('context__lev1__lev2').distinct()
AbcModel.objects.values_list('context__lev1__lev2', flat=True).distinct()

编辑: JSON 字段是来自 django.contrib.postgres.fields 的官方 django JSONField

4

2 回答 2

19

所以我找到了一个解决方案,这适用于 django 1.10 及更高版本。我使用 KeyTransform 来注释和提取下一个键,并在其上做了一个 values_list。

from django.contrib.postgres.fields.jsonb import KeyTransform
extracted_query = AbcModel.objects.annotate(lev1=KeyTransform('lev1', 'context')).annotate(lev2=KeyTransform('lev', 'lev1'))

该查询允许我使用 lev1 和 lev2 作为模型中的普通字段,因此我可以对字段执行值、values_list 或任何其他有效查询。

Django 1.11 允许将两个变换嵌套在一个注释中,不确定 1.10 关于嵌套,因为我已升级到 1.11

于 2017-07-28T09:36:14.217 回答
3

这并不理想,但我能够通过将 json 字段添加为额外字段然后在该额外字段上调用值来实现此功能:

AbcModel.objects.extra(select={
    "extra_field": "context->'lev1'->'lev2'"
}).values('extra_field').distinct()
AbcModel.objects.extra(select={
    "extra_field": "context->'lev1'->'lev2'"
}).values_list('extra_field', flat=True).distinct()
于 2017-07-25T14:19:18.477 回答