首页 > 解决方案 > 如何将 keyTextTransform() 用于嵌套 json?

问题描述

我的模型有一个 json 字段。我可以使用以下查询访问 jsonfield['key1']

from django.contrib.postgres.fields.jsonb import KeyTextTransform
MyModel.objects.annotate(val=KeyTextTransform('key1', 'jsonfield')).order_by('val')

但是如何访问像 jsonfield['key1']['key2'] 甚至更多嵌套的键?

这不可能是唯一的解决方案,对吧?

MyModel.objects.annotate(val=KeyTextTransform('key2', (KeyTextTransform('key1', 'jsonfield'))).order_by('val')

标签: jsondjangopostgresql

解决方案


谢天谢地,困难的部分已经完成。KeyTextTransform是可组合的。我们所要做的就是编写它。

class NestableKeyTextTransform:
    def __new__(cls, field, *path):
        if not path:
            raise ValueError("Path must contain at least one key.")
        head, *tail = path
        field = KeyTextTransform(head, field)
        for head in tail:
            field = KeyTextTransform(head, field)
        return field


MyModel.objects.annotate(
    single_nested_value=NestableKeyTextTransform(
      "json_field", "query", "name"
    ),
    array_access=NestableKeyTextTransform(
      "json_field", "query", "address_line", 1
    ),
)

尽管我想指出这可能是一种更好的方法:

from django.db.models import F

MyModel.objects.annotate(
    single_nested_value=F("json_field__query__name"),
    array_access=F("json_field__query__address_line__1"),
)

推荐阅读