Możesz użyć jsonb_extract_path_text przez Func obiekt jako alternatywa dla transformacji pola:
Pet.annotate(dinner=Func(
F('data'), Value('diet'), Value('dinner'),
function='jsonb_extract_path_text')) \
.values('dinner') \
.annotate(total=Count('dinner'))
Powód, dla którego pole przekształca data__diet__dinner
fails to błąd w Django, gdy wchodzisz głębiej niż tylko jeden poziom w strukturę json i użyj GROUP BY
w SQL. Pierwszy poziom (name
, animal
, diet
) powinno działać poprawnie.
Powodem wydaje się być to, że w przypadku przekształceń zagnieżdżonych Django zmienia używaną składnię SQL, przełączając się z pojedynczej wartości na listę, aby określić ścieżkę do struktury json.
To jest składnia używana dla nie zagnieżdżonych przekształceń json (=pierwszy poziom):
"appname_pet"."data" -> 'diet'
A to jest składnia używana dla przekształceń zagnieżdżonych (głębszych niż pierwszy poziom):
"appname_pet"."data" #> ARRAY['diet', 'dinner']
Podczas konstruowania zapytania, Django dusi się na tej liście podczas opracowywania wymaganego GROUP BY
klauzule. Nie wydaje się to być nieuniknionym ograniczeniem; obsługa przekształceń jest całkiem nowa i prawdopodobnie jest to jeden z niedopracowanych jeszcze problemów. Jeśli więc otworzysz bilet Django
, może to zadziałać tylko kilka wersji dalej.