2012-04-16 9 views
6

tôi có các mô hình sau:Loại trừ toàn bộ QuerySet từ kết quả

class LibraryEntry(models.Model): 
    player = models.ForeignKey(Player) 
    player_lib_song_id = models.IntegerField() 
    title = models.CharField(max_length=200) 
    artist = models.CharField(max_length=200) 
    album = models.CharField(max_length=200) 
    track = models.IntegerField() 
    genre = models.CharField(max_length=50) 
    duration = models.IntegerField() 
    is_deleted = models.BooleanField(default=False) 

    class Meta: 
    unique_together = ("player", "player_lib_song_id") 

    def __unicode__(self): 
    return "Library Entry " + str(self.player_lib_song_id) + ": " + self.title 

class BannedSong(models.Model): 
    lib_entry = models.ForeignKey(LibraryEntry) 

    def __unicode__(self): 
    return "Banned Library Entry " + str(self.lib_entry.title) 

Tôi muốn làm một truy vấn như thế này:

banned_songs = BannedSong.objects.filter(lib_entry__player=activePlayer) 
available_songs = LibraryEntry.objects.filter(player=activePlayer).exclude(banned_songs) 

Về cơ bản nếu một bài hát bị cấm, tôi muốn loại trừ từ bộ bài hát có sẵn của tôi. Có cách nào để làm điều này trong Django?

+0

Bạn có thể không làm cho 'is_banned' một lĩnh vực boolean của mô hình LibraryEntry của bạn? – jimw

+0

Có, nhưng rất ít bài hát thực sự bị cấm so với con số không có. Tôi nghĩ rằng việc thêm một trường boolean mà phần lớn chỉ là một giá trị là biểu mẫu không hợp lệ. –

+1

Tôi sẽ không nói như vậy, nhưng tôi cho rằng đó là vấn đề về hương vị. – jimw

Trả lời

11
banned_song_ids = (BannedSong.objects.filter(lib_entry__player=activePlayer) 
              .values_list('lib_entry', flat=True)) 

available_songs = (LibraryEntry.objects.filter(player=activePlayer) 
              .exclude('id__in' = banned_song_ids)) 

Cách khác là:

available_songs = (LibraryEntry.objects.filter(player=activePlayer) 
              .filter(bannedsong__isnull = True)) 
+0

Tôi đã thử điều này trước khi thực sự và nó không hoạt động. Django so sánh trường id của mỗi bộ. Tôi muốn nó so sánh trường id của LibraryEntry được thiết lập với trường lib_id của tập hợp restricted_songs. Không so sánh id với id. –

+0

@KurtisNusbaum Tôi đã viết rằng trước khi tôi nhận ra 'banned_songs' là một queryset từ một mô hình khác, chứ không phải là cùng một mô hình. Tôi đã cập nhật nó để sử dụng 'values_list'. – agf

+0

Tuyệt vời. Điều đó sẽ làm việc khá tốt thực sự. Mặc dù tôi sợ một số vấn đề hiệu suất trong trường hợp cấm_songs là lớn. Nhưng như tôi đã nói, tôi không dự đoán nó lớn. Nếu tôi làm cho nó một OneToOneField thay vì một chìa khóa nước ngoài, điều đó thay đổi mọi thứ? –