Můžete použít jsonb_extract_path_text prostřednictvím Func objekt jako alternativa k transformaci pole:
Pet.annotate(dinner=Func(
F('data'), Value('diet'), Value('dinner'),
function='jsonb_extract_path_text')) \
.values('dinner') \
.annotate(total=Count('dinner'))
Důvod, proč se pole transformuje data__diet__dinner
Selže je chyba v Django, když jdete hlouběji než jen o jednu úroveň do struktury json a použijte GROUP BY
v SQL. První úroveň (name
, animal
, diet
) by mělo fungovat dobře.
Zdá se, že důvodem je to, že pro vnořené transformace Django změní použitou syntaxi SQL a přepne z jedné hodnoty na seznam, aby určil cestu ke struktuře json.
Toto je syntaxe použitá pro nevnořené transformace json (=první úroveň):
"appname_pet"."data" -> 'diet'
A toto je syntaxe používaná pro vnořené transformace (hlubší než první úroveň):
"appname_pet"."data" #> ARRAY['diet', 'dinner']
Při sestavování dotazu se Django dusí tímto seznamem, zatímco vypracovává požadované GROUP BY
doložky. Nezdá se, že by to bylo nevyhnutelné omezení; podpora pro transformace je zcela nová a toto je možná jeden z problémů, které ještě nebyly vyřešeny. Pokud tedy otevřete lístek Django
, může to fungovat jen v několika verzích.