django

django-model之定义查询集API

2018-08-26  本文已影响34人  陆_志东

下面的这个例子允许你直接从自定义的管理器Person.people 中调用authors() 和editors()。
注意Person.objects 也可以调用authors() 和editors()。因为定义的方法会被复制到管理器
文章最下面有复制的原则,哪些方法会被允许复制,如果你不想允许复制到管理器,请查看文章最下面
因为objects 是 models.Manager() 的实例,并没有添加authors() 和editors()方法

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'))))
    objects = models.Manager()
    people = PersonManager()

上面的实例可以通过QuerySet.as_manager()方法来简化
通过QuerySet.as_manager()创建的管理器 实例,实际上等价于上面例子中的PersonManager。

class PersonQuerySet(models.QuerySet):
    def authors(self):
        return self.filter(role='A')

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


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'))))
    objects = models.Manager()
    people = PersonQuerySet.as_manager()

注意:并不是每个查询集的方法都在管理器层面上有意义
方法复制到管理器的原则:

class CustomQuerySet(models.QuerySet):
    # Available on both Manager and QuerySet.  在Manager和QuerySet上都可用。
    def public_method(self):
        return

    # Available only on QuerySet. 只在QuerySet可用。
    def _private_method(self):
        return

    # Available only on QuerySet. 只在QuerySet可用。
    def opted_out_public_method(self):
        return
    opted_out_public_method.queryset_only = True

    # Available on both Manager and QuerySet.  在Manager和QuerySet上都可用。
    def _opted_in_private_method(self):
        return
    _opted_in_private_method.queryset_only = False
上一篇 下一篇

猜你喜欢

热点阅读