2011-08-09 33 views
8

Tôi ngạc nhiên khi câu hỏi này dường như chưa tồn tại. Nếu có, hãy giúp tôi tìm nó.Chú thích có điều kiện Django

Tôi muốn sử dụng chú thích (Đếm) và order_by, nhưng tôi không muốn đếm từng trường hợp của một đối tượng liên quan, chỉ những đối tượng đáp ứng một tiêu chí nhất định.

Để wit, rằng tôi có thể liệt kê nuốt bởi số lượng dừa xanh họ đã tiến hành:

swallow.objects.annotate(num_coconuts=Count('coconuts_carried__husk__color = "green"').order_by('num_coconuts') 

Trả lời

8

này nên được một cách đúng đắn.

swallow.objects.filter(
    coconuts_carried__husk__color="green" 
).annotate(
    num_coconuts=Count('coconuts_carried') 
).order_by('num_coconuts') 

Lưu ý rằng khi bạn lọc cho trường có liên quan, trong SQL thô nó được dịch thành LEFT JOIN cộng với WHERE. Cuối cùng, chú thích sẽ hành động trên tập kết quả, chỉ chứa các hàng liên quan được chọn từ bộ lọc đầu tiên.

+0

Trên thực tế điều này dường như để làm việc, nhưng vì lý do bạn chỉ ra, đó là hoàn toàn phản tác dụng trực quan. Tôi mong đợi queryset này cho tôi tất cả những con én đã từng mang ít nhất một quả dừa xanh, được yêu cầu bởi tổng số dừa được mang bất kể màu nào. – jMyles

+1

@jMyles: tài liệu chỉ ra rằng điều này phụ thuộc vào [thứ tự của mệnh đề chú thích và bộ lọc] (https://docs.djangoproject.com/en/1.3/topics/db/aggregation/#order-of-annotate- và-filter-clauses) - theo cách khác, nó sẽ hoạt động như bạn mô tả. –

+2

Điều gì sẽ xảy ra nếu bạn muốn bao gồm những quả không nuốt bất kỳ quả dừa xanh nào? –

3

Đối với Django> = 1.8:

from django.db.models import Sum, Case, When, IntegerField 

swallow.objects.annotate(
    num_coconuts=Sum(Case(
     When(coconuts_carried__husk__color="green", then=1), 
     output_field=IntegerField(), 
    )) 
).order_by('num_coconuts') 
Các vấn đề liên quan