2012-08-24 18 views
8

Trong thiết lập sau, tôi muốn một QuerySet có một danh sách các dự án, mỗi chú thích với tổng của tất cả các thời gian nhiệm vụ của nó (như tasks_duration) và tổng của tất cả các nhiệm vụ của nó ' subtask duration (như subtasks_duration). Mô hình của tôi (giản thể) trông như thế này:nhiều chú thích Cụm từ tổng sản lượng trả lời tăng cao

class Project(models.Model): 
    pass 

class Task(models.Model): 
    project = models.ForeignKey(Project) 
    duration = models.IntegerField(blank=True, null=True) 

class SubTask(models.Model): 
    task = models.ForeignKey(Task) 
    duration = models.IntegerField(blank=True, null=True) 

tôi làm cho QuerySet của tôi như thế này:

Projects.objects.annotate(tasks_duration=Sum('task__duration'), subtasks_duration=Sum('task__subtask__duration')) 

Liên quan đến hành vi được giải thích trong Django annotate() multiple times causes wrong answers tôi nhận được một tasks_duration đó là cao hơn nhiều so với nó nên được. Các mệnh đề nhiều chú thích (Sum()) mang lại nhiều phép nối bên trong bên trái trong SQL kết quả. Chỉ với một cụm từ chú thích (Sum()) duy nhất cho task_duration, kết quả là chính xác. Tuy nhiên, tôi muốn có cả task_duration và subtasks_duration.

Cách thích hợp để thực hiện truy vấn này là gì? Tôi có một giải pháp làm việc cho mỗi dự án, nhưng đó là chậm trễ đáng ngạc nhiên. Tôi cũng có một cái gì đó tương tự làm việc với một cuộc gọi thêm(), nhưng tôi thực sự muốn biết nếu những gì tôi muốn là có thể với Django tinh khiết.

+0

Bạn đã thử 'tasks_duration = Sum ('task__duration', khác biệt = True), subtasks_duration = Sum ('task__subtask__duration', khác biệt = True) 'như được đề cập trong câu hỏi khác mà bạn đã liên kết? – jpic

+0

Điều đó sẽ chỉ phục vụ để tính các giá trị thời lượng riêng biệt, không phải là những gì tôi muốn. Trong tò mò tôi đã thử nó, vẫn mang lại giá trị không chính xác. (các khoảng thời gian khác nhau) –

+0

Bao giờ tìm thấy một giải pháp cho việc này? Tôi đang cố gắng để chú thích một tổng và đếm trên một queryset, và số tiền tiếp tục nhận được nhân ... – StephenTG

Trả lời

1

Tôi cũng nhận được lỗi này. Chính xác cùng một mã. Nó hoạt động nếu tôi tập hợp một cách riêng biệt, nhưng một khi tôi cố gắng để có được cả hai khoản tiền cùng một lúc, một trong số họ nhận được một yếu tố 2 cao hơn, và một yếu tố khác 3.

Tôi không biết tại sao Django hoạt động này đường. Tôi đã gửi báo cáo lỗi tại đây: https://code.djangoproject.com/ticket/19011 Bạn cũng có thể muốn theo dõi báo cáo lỗi.

+0

Nó không thực sự là một lỗi trong Django nhưng là một vấn đề phức tạp của việc thực hiện các truy vấn tổng hợp cho cơ sở dữ liệu. Ngay cả khi bạn đã tự viết SQL, bạn sẽ phải giải quyết vấn đề này. – benjaoming

+1

Liên kết đến báo cáo lỗi có liên quan: https://code.djangoproject.com/ticket/10060 – benjaoming

+0

Lỗi này vẫn chưa được khắc phục. – sobolevn

1

Lỗi được báo cáo here nhưng lỗi chưa được giải quyết ngay cả trong Django 1.11. Vấn đề có liên quan đến việc tham gia hai bảng trong quan hệ ngược lại. Lưu ý rằng thông số riêng biệt hoạt động tốt đối với Đếm nhưng không hoạt động đối với Tổng. Vì vậy, bạn có thể sử dụng một thủ thuật và viết một ORM như dưới đây:

Projects.objects.annotate(
     temp_tasks_duration=Sum('task__duration'), 
     temp_subtasks_duration=Sum('task__subtask__duration'), 
     tasks_count=Count('task'), 
     tasks_count_distinct=Count('task', distinct=True), 
     task_subtasks_count=Count('task__subtask'), 
     task_subtasks_count_distinct=Count('task__subtask', distinct=True), 
).annotate(
     tasks_duration=F('temp_tasks_duration')*F('tasks_count_distinct')/F('tasks_count'), 
     subtasks_duration=F('temp_subtasks_duration')*F('subtasks_count_distinct')/F('subtasks_count'), 
) 
Các vấn đề liên quan