django queryset“包含”列表,而不是字符串

时间:2014-09-08 23:25:59

标签: python sql django django-queryset

我试图搜索段落的查询集,该段落具有将每个段落映射到章节的多对多字段。每一章都是一本书的一部分,每一章都有多位作者,每一位作者都可以有多本书,因而也有段落。我想从返回的段落查询集中排除特定作者。

简化模型:

class Paragraph(models.Model):
    id = models.AutoField(primary_key = True)
    chapter = models.ForeignKey(Chapter, related_name = 'paragraphs')

class Chapter(models.Model):
    id = models.AutoField(primary_key = True)
    book = models.ForeignKey(Book, related_name = 'chapters')

class Book(models.Model):
    id = models.AutoField(primary_key = True)
    authors = models.ManyToManyField(User, related_name = 'books')

首先我尝试了:

paragraphs.exclude(chapter__book__authors__contains = author)

这不起作用,因为 author 是一个对象,而不是一个字符串。我可以在Python中手动执行此操作:

[p for p in paragraphs if author not in p.chapter.book.authors.filter()]

但这比QuerySet方式慢得多。我真正想说的是:

paragraphs.exclude(author__in = chapter__book__authors)

然而,这并不起作用,因为"作者"是一个单独查询的对象,我无法从中获取,因此它不是有效的Django。我如何表达这一点,将对象保持为实际对象而不是字符串?

修改

如果我跑

paragraphs.exclude(chapter__book__authors__id = author.id)

它几乎可以运作,但仍然包括一本书有多位作者而其中一位作者是我想忽略的结果。

1 个答案:

答案 0 :(得分:0)

如果author是一个对象,您应该能够通过传递author对象的字段来实现您想要的目标。

例如

paragraphs.exclude(chapter__book__authors__contains=author.name)