Você pode usar jsonb_extract_path_text por meio de um Função objeto como uma alternativa para a transformação de campo:
Pet.annotate(dinner=Func(
F('data'), Value('diet'), Value('dinner'),
function='jsonb_extract_path_text')) \
.values('dinner') \
.annotate(total=Count('dinner'))
O motivo pelo qual o campo transforma
data__diet__dinner
falha é um erro dentro do Django quando você vai mais fundo do que apenas um nível na estrutura json e use GROUP BY
no SQL. O primeiro nível (name
, animal
, diet
) deve funcionar bem. A razão parece ser que, para transformações aninhadas, o Django altera a sintaxe SQL usada, alternando de um único valor para uma lista para especificar o caminho para a estrutura json.
Esta é a sintaxe usada para transformações json não aninhadas (=primeiro nível):
"appname_pet"."data" -> 'diet'
E esta é a sintaxe usada para transformações aninhadas (mais profundas que o primeiro nível):
"appname_pet"."data" #> ARRAY['diet', 'dinner']
Ao construir a consulta, o Django engasga nessa lista enquanto trabalha com o
GROUP BY
necessário cláusulas. Esta não parece ser uma restrição inevitável; o suporte para transformações é bastante novo, e este é possivelmente um dos problemas que ainda não foram resolvidos. Então, se você abrir um ticket do Django
, isso pode funcionar apenas em algumas versões.