Вы можете использовать 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
является ошибка в 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 , это может просто сработать на несколько версий.