Django模型管理器或Django查询集

3

我在阅读django 文档,发现这两个类看起来很相似:

以下是django文档中的示例:

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()

在示例代码中,您可以看到PersonQuerySet中的代码可以移动到PersonManager(或将管理器移动到查询集)- 我的意思是我可以毫不费力地将一个合并到另一个中)

那么管理器和查询集之间有什么区别?它们是否具有不同的用例?还是应该只使用其中一个并忽略另一个的存在?

3个回答

3
您现在可以使用from_queryset()方法来更改您的管理器的基本Queryset。这使您只需定义一次Queryset方法和管理器方法即可。
来自文档的说明:
对于高级用法,您可能需要自定义Manager和自定义QuerySet。您可以通过调用Manager.from_queryset()来实现这一点,它将返回基于您的基本Manager的子类,并带有自定义QuerySet方法的副本:
class PersonQuerySet(models.QuerySet):
    def authors(self):
        return self.filter(role='A')

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

class BasePersonManager(models.Manager):
    pass

PersonManager = BasePersonManager.from_queryset(PersonQuerySet)

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()

1
谢谢,但我的问题是manager和queryset之间有什么区别?以及了解它们的使用情况。 - aliva
6
经理用于表范围操作,而查询集则用于记录子集。 - maazza
1
@maazza 这个评论非常有帮助,一句话让我明白了一切。 - motam

2
这有点奇怪。如果您想在QuerySet中编写自定义方法并且希望通过Manager类访问它们,则必须在Manager类中实现这些方法。这看起来不太好,因为Django尽可能地遵循DRY原则,因此提供了helper as_manager()。
因此,回答您的问题,这不是两种不同情况,而是一个特殊情况的示例,在该情况下,您希望通过自定义Manager使用自定义QuerySet方法。

0
为了保持DRY,django有这个方法as_manager(),你不必在两个地方重复需要的代码。
然而,这个答案提供了一个非常好的例子,回答了关于这两个类的区别的问题。我添加了##注释。
Blog.objects.count()  # Total number of blogs  ## Manager
Blog.objects.filter(status='PUBLISHED').count()  # Number of published blogs ## QuerySet

这在下面也很清楚:

In [7]: type(MyModel.objects.filter())
Out[7]: django.db.models.query.QuerySet

In [8]: type(MyModel.objects)
Out[8]: django.db.models.manager.Manager

1
谢谢,但我的问题是管理器和查询集之间有什么区别?以及了解它们的使用情况。 - aliva
@aliva 我读了被接受的答案,但我不明白发生了什么。当我阅读链接的答案时,通过这个例子来说明差异(请参见末尾的“##”),我有一种感觉,只是一个概念。要了解更多详细信息,您可能应该查看源代码 - raratiru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接