Postgres:使用 django 对 json 键进行值查询
Postgres: values query on json key with django
我需要在 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 JSON 来自 django.contrib.postgres.fields
的字段
这并不理想,但我能够通过将 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()
所以我找到了一个解决方案,它适用于 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
我需要在 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 JSON 来自 django.contrib.postgres.fields
的字段这并不理想,但我能够通过将 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()
所以我找到了一个解决方案,它适用于 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