Django中写自定义QuerySet类有什么用

What is the use of writing custom QuerySet classes in Django

我正在浏览模型管理器的 Django 文档。我看到 in this section 我看到 model.QuerySet class 被自定义 QuerySet class 覆盖,它有两种方法 returns 通过过滤 role='A' 或角色='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 中过滤的需求是什么,而我们本可以像这样在模型管理器本身中完成过滤。

class PersonManager(models.manager):
    def authors(self):
        return self.filter(role='A') 

    def editors(self):
        return self.filter(role='E') 

请帮助理解差异。提前谢谢你。

在使用 Django 的 ORM 进行查询时,经常会看到人们在查询集上使用 chaining 方法,例如:

queryset.filter(...).annotate(...).order_by(...)

此处的每个方法 returns 一个 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

而如果我们使用自定义查询集来完成此操作,那么第二个查询集也会起作用。这是因为如果我们在管理器上声明该方法,查询集将不会真正拥有它,因此我们对该方法的链接将失败。