Bạn có thể sử dụng jsonb_extract_path_text qua Func đối tượng thay thế cho chuyển đổi trường:
Pet.annotate(dinner=Func(
F('data'), Value('diet'), Value('dinner'),
function='jsonb_extract_path_text')) \
.values('dinner') \
.annotate(total=Count('dinner'))
Lý do tại sao chuyển đổi trường data__diet__dinner
không thành công là một lỗi trong Django khi bạn đi sâu hơn chỉ một cấp vào cấu trúc json và sử dụng GROUP BY
trong SQL. Cấp độ đầu tiên (name
, animal
, diet
) sẽ hoạt động tốt.
Lý do dường như là đối với các phép biến đổi lồng nhau, Django thay đổi cú pháp SQL được sử dụng, chuyển từ một giá trị duy nhất sang một danh sách để chỉ định đường dẫn vào cấu trúc json.
Đây là cú pháp được sử dụng cho các phép biến đổi json không lồng nhau (=mức đầu tiên):
"appname_pet"."data" -> 'diet'
Và đây là cú pháp được sử dụng cho các phép biến đổi lồng nhau (sâu hơn mức đầu tiên):
"appname_pet"."data" #> ARRAY['diet', 'dinner']
Trong khi xây dựng truy vấn, Django mắc kẹt trên danh sách đó trong khi giải quyết GROUP BY
bắt buộc điều khoản. Đây dường như không phải là một hạn chế không thể tránh khỏi; hỗ trợ cho các phép chuyển đổi còn khá mới và đây có thể là một trong những điểm khó khăn vẫn chưa được giải quyết. Vì vậy, nếu bạn mở vé Django
, điều này có thể chỉ hoạt động với một vài phiên bản sau.