aggregate() thu cả QuerySet về một dict duy nhất; annotate() gắn thêm một cột tính toán vào từng dòng và vẫn trả về QuerySet.
python
from django.db.models import Avg, Count
# one summary value for the whole table
Book.objects.aggregate(Avg('price'))
# -> {'price__avg': 120.5}
# one extra field per row
authors = Author.objects.annotate(book_count=Count('book'))
authors[0].book_count # 12Về SQL: aggregate() sinh một SELECT AVG(...) không GROUP BY; annotate() sinh JOIN + GROUP BY theo khoá chính của model gốc.
Hệ quả thực tế: kết quả annotate() vẫn filter() / order_by() tiếp được theo cột vừa gắn (.order_by('-book_count')), còn aggregate() là điểm kết thúc chuỗi — gọi xong là ra giá trị, không nối thêm được.