我正在浏览Django模型管理器文档。我在这个部分看到了那个模型。QuerySet类被一个自定义QuerySet类覆盖,该类有两个方法,通过筛选role='a'或role='E'来返回查询集。
class PersonQuerySet(models.QuerySet):
def authors(self):
return self.filter(role='A')
def editors(self):
return self.filter(role='E')
class PersonManager(models.Manager):
def get_queryset(self):
return PersonQuerySet(self.model, using=self._db)
def authors(self):
return self.get_queryset().authors()
def editors(self):
return self.get_queryset().editors()
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
role = models.CharField(max_length=1, choices=[('A', _('Author')), ('E', _('Editor'))])
people = PersonManager()
但我不明白在QuerySet类中过滤的需要是什么,而我们本可以在模型管理器中这样做。
class PersonManager(models.manager):
def authors(self):
return self.filter(role='A')
def editors(self):
return self.filter(role='E')
请帮助理解差异。提前谢谢。
当使用Django的ORM进行查询时,人们在查询集上链接方法是很常见的,例如:
queryset.filter(...).annotate(...).order_by(...)
这里的每个方法都返回QuerySet
的一个实例,我们可以在该实例上应用更多方法。
现在让我们假设我们要使用您的解决方案,并在模型管理器中实现我们的方法。在这种情况下,让我们考虑以下片段:
print(type(Person.objects)) # prints the manager class
print(type(Person.objects.all())) # prints the queryset class
Person.objects.authors() # Succeeds
Person.objects.all().authors() # likely (might be some other) raises an AttributeError
然而,如果我们使用自定义查询集来完成此操作,那么第二个查询集也会起作用。这是因为,如果我们在管理器上声明了该方法,查询集将不会真正拥有它,因此我们对该方法的链接将失败。