Можете да използвате jsonb_extract_path_text чрез Func обект като алтернатива на трансформацията на полето:
Pet.annotate(dinner=Func(
F('data'), Value('diet'), Value('dinner'),
function='jsonb_extract_path_text')) \
.values('dinner') \
.annotate(total=Count('dinner'))
Причината, поради която полето трансформира data__diet__dinner
fails е грешка в Django, когато отидете по-дълбоко от само едно ниво в json структурата и използвайте GROUP BY
в SQL. Първото ниво (name
, animal
, diet
) трябва да работи добре.
Причината изглежда е, че за вложени трансформации Django променя използвания SQL синтаксис, превключвайки от единична стойност към списък, за да посочи пътя към json структурата.
Това е синтаксисът, използван за невложени json трансформации (=първо ниво):
"appname_pet"."data" -> 'diet'
И това е синтаксисът, използван за вложени трансформации (по-дълбоко от първо ниво):
"appname_pet"."data" #> ARRAY['diet', 'dinner']
Докато конструира заявката, Django се задавя от този списък, докато разработва необходимия GROUP BY
клаузи. Това не изглежда неизбежно ограничение; поддръжката за трансформации е доста нова и това вероятно е един от недостатъците, които все още не са разработени. Така че, ако отворите бикет за Django
, това може да работи само няколко версии надолу.