下面的这个例子允许你直接从自定义的管理器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()
注意:
并不是每个查询集的方法都在管理器层面上有意义
方法复制到管理器的原则:
- 公共方法默认被复制。
- 私有方法(前面带一个下划线)默认不被复制。
- 带queryset_only 属性,并且值为False的方法总是被复制。
- 带 queryset_only 属性,并且值为True 的方法不会被复制。
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
网友评论