我正在寻找一种返回与自定义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
。
答案 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)