Postgres:使用django在json键上查询值

时间:2017-03-08 15:47:14

标签: python django django-models django-orm django-postgresql

我需要在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

2 个答案:

答案 0 :(得分:9)

所以我找到了一个解决方案,这适用于django 1.10及以上版本。 我使用KeyTransform来注释和提取nexted键,并在其上执行了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允许将两个Transforms嵌套在一个注释中,不确定关于嵌套的1.10,因为我已升级到1.11

答案 1 :(得分:1)

它并不理想,但我能够通过将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()