您可以在管理器中封装过滤、注释、子查询等。例如:
class ActiveManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(
active=True
)
然后将其应用于具有active 字段的模块:
class MyActiveModel(models.Model):
active = models.BooleanField(default=False)
objects = ActiveManager()
现在如果我们使用MyActiveModel.objects.all(),它只会检索active = True 的记录。因此我们不需要在所有视图中应用此过滤,我们可以像在任何模型中一样使用objects,它会透明地过滤对象。
如果您想对查询集进行扩展,也经常使用Manager。
例如我们可以定义一个AuthorQuerySet,它提供了一个额外的方法.of_user(…),例如保留给定用户是作者的记录,或者用户是超级用户,检索所有记录:
class AuthorQuerySet(models.QuerySet):
def from_user(self, user):
if user.is_superuser:
return self
else:
return self.filter(author=user)
然后与允许执行此过滤的经理合作:
from django.conf import settings
class Post(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
objects = AuthorQuerySet.as_manager()
然后我们可以检索用户可以看到的对象:
Post.objects<strong>.filter_user(myuser)</strong>
或在过滤器链中执行此操作:
Post.objects.filter(title__istartswith='The').<strong>filter_user(myuser)</strong>
因此它主要处理封装逻辑,例如过滤、注释等只定义一次,然后以透明的方式在视图中使用。换句话说,视图不必担心它只会检索活动对象,管理器会处理这个问题。
这对代码分段有何帮助?
模型专注于在数据库中存储记录并呈现数据。通常它应该不决定你在什么情况下看到什么记录。 views 用于此目的。但是如果逻辑相同,那么在视图中编写它是没有意义的,因为如果(几乎)总是应该发生的过滤、注释等被复制到一个大量的意见。通过在管理器中实现这一点,我们在模型和视图之间有一个层,可以始终以相同的方式过滤、注释等数据。
管理者可以做哪些视图或模型方法不能做的事情?
可以对每个视图重复一次相同的过滤代码,但这使得以后在流程中很难更改该逻辑,因为那时应该查看这些模型在哪些视图中被访问,并更改all 这些观点。这样很容易忽略某些内容,从而导致状态不一致。
还可以在模型中定义静态方法来进行过滤。但是相同的模型可以与多个经理一起使用,这样,根据情况,选择另一个模型。
换句话说,它是模型和视图之间的一层,它与模型以多对一的方式工作,与视图代码以多对多的方式工作。