Du kan bruge jsonb_extract_path_text via en Func objekt som et alternativ til felttransformationen:
Pet.annotate(dinner=Func(
F('data'), Value('diet'), Value('dinner'),
function='jsonb_extract_path_text')) \
.values('dinner') \
.annotate(total=Count('dinner'))
Grunden til, at feltet transformerer data__diet__dinner
fails er en fejl i Django, når du går dybere end blot ét niveau ind i json-strukturen og brug GROUP BY
i SQL. Det første niveau (name
, animal
, diet
) burde fungere fint.
Årsagen ser ud til at være, at for indlejrede transformationer ændrer Django den anvendte SQL-syntaks ved at skifte fra en enkelt værdi til en liste for at angive stien til json-strukturen.
Dette er den syntaks, der bruges til ikke-indlejrede json-transformationer (=første niveau):
"appname_pet"."data" -> 'diet'
Og dette er den syntaks, der bruges til indlejrede transformationer (dybere end første niveau):
"appname_pet"."data" #> ARRAY['diet', 'dinner']
Mens han konstruerer forespørgslen, kvæler Django på listen, mens han udarbejder den nødvendige GROUP BY
klausuler. Dette synes ikke at være en uundgåelig begrænsning; understøttelsen af transformationer er ret ny, og dette er muligvis et af de knæk, der ikke er blevet løst endnu. Så hvis du åbner en Django-billet
, dette kan måske bare fungere et par versioner ned ad linjen.