有没有办法返回自定义Django QuerySet的反义词

时间:2019-07-19 00:46:37

标签: django django-models

我正在寻找一种返回与自定义Django管理器查询集完全相反的方法。我正在一个已经定义了一些查询集的项目中,我想得到相反的结果。为简单起见,我将使用docs中的示例。假设我有一个Book模型和一个DahlManager,它通过author='Roald Dahl'过滤了这些书。假设在DahlManager内部,我有另一种方法get_childrens_books仅返回他的孩子的书,类似is_for_children=True。有没有一种方法可以与这种新方法相反,而无需编写完全独立的过滤器或方法?我想要类似Books.dahl_objects.get_childrens_books().exclude()Books.dahl_objects.exclude(get_childrens_books)的东西,而不是向DahlManager添加其他方法。这样做的动机是,我可以看到添加大量重复代码的潜力。我不想为我写的每个not_filter写一个filter

2 个答案:

答案 0 :(得分:1)

您可以使用自定义的查询集功能来完成您要问的事情:

class DahlBookQueryset(models.Queryset):
    def oposite(self):
        current_ids = self.values_list('id', flat=True)
        return Book.dahl_objects.all().exclude(id__in=current_ids)

# First, define the Manager subclass.
class DahlBookManager(models.Manager):
    def get_queryset(self):
        return DahlBookQueryset(self.model, using=self._db).filter(author='Roald Dahl')

    def get_children_books(self):
        return self.get_queryset().filter(children=True)

# Then hook it into the Book model explicitly.
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

    objects = models.Manager() # The default manager.
    dahl_objects = DahlBookManager() # The Dahl-specific manager.

查询将为Books.dahl_objects.get_childrens_books().oposite()

如果您不明白,请随时提出疑问。

答案 1 :(得分:0)

django的对象管理器具有exclude()方法,但是您需要在过滤过程中使用该方法。换句话说,如果像get_childrens_books()方法那样先创建一个查询集,则不能相反。相反,您可以即时使用exclude()

假设您要过滤不是儿童图书的图书。这将起作用:

not_children_books = Books.objects.exclude(children=True)