2012-04-16 14 views
6

tengo los siguientes modelos:Excluir toda QuerySet de los resultados

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) 

me gustaría hacer una consulta como esta:

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

Básicamente, si se prohibió una canción, que desea excluir de mi conjunto de canciones disponibles. ¿Hay alguna manera de hacer esto en Django?

+0

¿No puedes hacer 'is_banned' un campo booleano de su modelo LibraryEntry? – jimw

+0

Sí, pero muy pocas canciones en realidad serán prohibidas en comparación con el número que no lo son. Pensé que agregar un campo booleano que en su mayor parte solo va a ser un valor es una mala forma. –

+1

No diría eso, pero supongo que es una cuestión de gusto. – jimw

Respuesta

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)) 

La alternativa es:

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

Intenté esto antes de hecho y no funciona. Django compara el campo de id de cada conjunto. Quiero que compare el campo id del conjunto LibraryEntry con el campo lib_id del conjunto banned_songs. No compare la identificación a la identificación. –

+0

@KurtisNusbaum Escribí eso antes de darme cuenta de que 'banned_songs' era un conjunto de preguntas de un modelo diferente, en lugar del mismo modelo. Lo actualicé para usar una 'values_list'. – agf

+0

Impresionante. Eso debería funcionar bastante bien en realidad. Aunque tengo miedo de algunos problemas de rendimiento en el caso de banned_songs es grande. Pero como dije, no anticipo que sea grande. Si lo hago un OneToOneField en lugar de una clave externa, ¿eso cambia las cosas? –

Cuestiones relacionadas