【问题标题】:Exclude entire QuerySet from results从结果中排除整个 QuerySet
【发布时间】:2012-04-28 07:17:07
【问题描述】:

我有以下型号:

 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)

我想做这样的查询:

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

基本上,如果一首歌曲被禁止,我想将其从我的可用歌曲集中排除。有没有办法在 Django 中做到这一点?

【问题讨论】:

  • 您不能将“is_banned”设为您的 LibraryEntry 模型的布尔字段吗?
  • 是的,但与没有被禁止的歌曲相比,实际上很少有歌曲会被禁止。我想添加一个布尔字段,它在大多数情况下只会是一个值是错误的形式。
  • 我不会这么说,但我想这是一个品味问题。
  • 我不明白为什么BannedSong 有一个ForeignKey - 如果你真的希望BannedSong 成为一个单独的模型,它不应该是OneToOneField(它应该'不是)?

标签: django django-models django-queryset


【解决方案1】:
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))

替代方案是:

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

【讨论】:

  • 我以前试过这个,但它不起作用。 Django 比较每个集合的 id 字段。我希望它将 LibraryEntry 集的 id 字段与banned_songs 集的 lib_id 字段进行比较。不将 id 与 id 进行比较。
  • @KurtisNusbaum 在我意识到banned_songs 是来自不同模型而不是同一个模型的查询集之前,我写道。我将其更新为使用values_list
  • 太棒了。这实际上应该工作得很好。虽然我担心在banned_songs很大的情况下会出现一些性能问题。但就像我说的,我预计它不会很大。如果我将其设为 OneToOneField 而不是外键,那会改变吗?
  • bannedsong__isnull 有效!正是我想要的。太棒了,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 2013-06-07
  • 2018-12-19
  • 2015-03-06
  • 2023-04-02
  • 2014-10-09
相关资源
最近更新 更多