2011-10-25 6 views
51

Giả sử tôi có một cái gì đó như thế này trong models.py tôi:Django lọc mô hình trên ManyToMany tính?

class Hipster(models.Model): 
    name = CharField(max_length=50) 

class Party(models.Model): 
    organiser = models.ForeignKey() 
    participants = models.ManyToManyField(Profile, related_name="participants") 

Bây giờ trong views.py của tôi, tôi muốn làm một truy vấn mà sẽ lấy một bữa tiệc cho người sử dụng nơi có hơn 0 người tham gia.

Something như thế này có lẽ:

user = Hipster.get(pk=1) 
hip_parties = Party.objects.filter(organiser=user, len(participants) > 0) 

cách tốt nhất để làm việc đó là gì?

+21

+1 chỉ để tạo đối tượng 'Hipster'. Quá buồn cười. – jathanism

+2

+1 cho các lớp học tuyệt vời, nhưng cũng là câu hỏi ngắn gọn ... – bhell

Trả lời

92

Nếu công trình này là cách tôi sẽ làm điều đó.

Cách tốt nhất có thể có nghĩa là rất nhiều thứ: hiệu suất tốt nhất, bảo trì tốt nhất, v.v. Do đó tôi sẽ không nói đây là cách tốt nhất, nhưng tôi thích gắn bó với các tính năng ORM càng nhiều càng tốt .

from django.db.models import Count 

user = Hipster.objects.get(pk=1) 
hip_parties = (Party.objects.annotate(num_participants=Count('participants')) 
          .filter(organiser=user, num_participants__gt=0)) 
+0

Đây là một cách hay để làm điều đó, mặc dù không ngắn gọn như câu trả lời đã chọn. – jathanism

+11

+1, "nhiều hơn Y", "ít hơn X" là tất cả được bảo hiểm ở đây, không chỉ null mà thực sự trả lời câu hỏi, "Django lọc mô hình trên ManyToMany đếm" –

+3

Điều này thực sự phải là câu trả lời được chấp nhận. – gregoltsov

28
Party.objects.filter(organizer=user, participants__isnull=False) 
Party.objects.filter(organizer=user, participants=None) 
+0

Tôi không nghĩ đây là giải pháp thanh lịch nhất, nhưng nó hoạt động trong trường hợp của tôi. Tôi sẽ vẫn nhìn xung quanh nếu có bất kỳ cách nào lành mạnh để làm điều đó. – Ska

+0

Điều gì không thanh lịch về giải pháp này? Đó chính xác là những gì bạn yêu cầu! :) Nó không hoàn toàn rõ ràng từ câu trả lời, nhưng bạn sẽ sử dụng một hoặc khác, không phải cả hai. Hai phương pháp tiếp cận cho cùng một vấn đề. – jathanism

+0

Tất nhiên sẽ thanh lịch hơn nếu người ta có thể tham khảo trực tiếp số. null không giống như len() == 0, hay tôi thiếu cái gì? – Ska

3

dễ dàng hơn với exclude:

# organized by user and has more than 0 participants 
Party.objects.filter(organizer=user).exclude(participants=None) 

Cũng trả về kết quả rõ rệt

0

Xuất phát từ @ Yuji-'Tomita'-Tomita câu trả lời, tôi cũng đã thêm .distinct (' id ') để loại trừ các bản ghi trùng lặp:

Party.objects.filter(organizer=user, participants__isnull=False).distinct('id') 

Do đó, mỗi bên chỉ được liệt kê một lần.