django模型管理器或django queryset

时间:2017-08-30 09:49:07

标签: django django-models

我正在阅读django docs,这两个类似乎相似,

这是来自django docs的样本:

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(或将管理器移动到查询集) - 我的观点是我可以合并到另一个没有任何问题)< / p>

那么manager和queryset之间有什么区别?他们有不同的用例吗?或者我应该只使用其中一个并忽略另一个?

3 个答案:

答案 0 :(得分:2)

这有点怪癖。基本上,如果您想在QuerySet AND 中编写自定义方法,您希望能够通过Manager类访问它们,必须也可以在Manager类中实现它们。这看起来不太好,因为Django试图尽可能干,因此辅助器as_manager()不是很干。

因此,要回答您的问题,这些不是两种不同的情况,而是一个特殊情况的示例,您希望通过自定义管理器使用自定义QuerySet方法。

答案 1 :(得分:1)

您现在可以在管理器上使用from_queryset()方法来更改其基本查询集。

这允许您仅定义一次Queryset方法和管理器方法

来自文档

  

对于高级用法,您可能需要自定义管理器和自定义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()

答案 2 :(得分:0)

为了保持DRY,django使用此方法as_manager(),在这里您不必复制两者中都需要的代码。

但是,this answer提供了一个很好的示例,它回答了关于这两个类的区别的问题。我添加了##条评论。

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