Puede usar jsonb_extract_path_text a través de un Func objeto como alternativa a la transformación de campo:
Pet.annotate(dinner=Func(
F('data'), Value('diet'), Value('dinner'),
function='jsonb_extract_path_text')) \
.values('dinner') \
.annotate(total=Count('dinner'))
La razón por la que el campo transforma data__diet__dinner
falla es un error dentro de Django cuando profundizas más de un nivel en la estructura json y usa GROUP BY
en el SQL. El primer nivel (name
, animal
, diet
) debería funcionar bien.
La razón parece ser que para las transformaciones anidadas, Django cambia la sintaxis SQL utilizada, cambiando de un solo valor a una lista para especificar la ruta a la estructura json.
Esta es la sintaxis utilizada para las transformaciones json no anidadas (=primer nivel):
"appname_pet"."data" -> 'diet'
Y esta es la sintaxis utilizada para las transformaciones anidadas (más profundas que el primer nivel):
"appname_pet"."data" #> ARRAY['diet', 'dinner']
Mientras construye la consulta, Django se atraganta con esa lista mientras resuelve el GROUP BY
requerido. cláusulas. Esto no parece ser una restricción inevitable; el soporte para transformaciones es bastante nuevo, y este es posiblemente uno de los problemas que aún no se han resuelto. Entonces, si abre un ticket de Django
, esto podría funcionar en algunas versiones más adelante.