【问题标题】:What is the use of writing custom QuerySet classes in Django在 Django 中编写自定义 QuerySet 类有什么用
【发布时间】:2021-06-16 13:28:24
【问题描述】:

我正在浏览模型管理器的 Django 文档。我看到in this section 我看到那个model.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') 

请帮助理解其中的区别。提前谢谢你。

【问题讨论】:

  • 不同之处在于您不能链接模型Manager中存在的方法。

标签: python django django-queryset


【解决方案1】:

在使用 Django 的 ORM 进行查询时,很常见的是人们在查询集上链接方法,例如:

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

这里的每个方法都返回一个QuerySet 的实例,我们可以在上面应用更多的方法。

现在让我们假设我们要使用您的解决方案并在模型管理器中实现我们的方法。在这种情况下,让我们考虑下面的 sn-p:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-21
    • 2012-02-04
    • 2011-04-07
    • 2011-03-16
    • 2019-04-10
    • 2012-08-16
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多