Django 管理器的顺序影响哪些函数?
我看了大部分文档,也在StackOverflow上查了一些资料,但还是找不到我想要的答案。先给你看看代码。
# Manager
class ActiveManager(models.Manager):
def get_query_set(self):
return super(ActiveManager, self).get_query_set().filter(is_active=True)
# Model
class ModelA(models.Model):
# ...
is_active = models.BooleanField()
objects = ActiveManager()
all_objects = models.Manager()
在我玩代码的时候,我发现如果我这样写,并使用 get_object_or_404()
,那么它会先用 ActiveManager
来查找所有活跃的记录,然后返回和我的查询相关的那条记录。不过,如果我把管理器的顺序调换一下:
class ModelA(models.Model):
# ...
all_objects = models.Manager()
objects = ActiveManager()
那么它就会使用默认的管理器,这里是 all_objects
来进行查询。我想知道这个顺序的变化会影响到哪些其他功能。
补充一下:我明白类中找到的第一个管理器会成为默认管理器,但我想知道具体有哪些功能会使用这个默认管理器(比如 get_object_or_404
)。
2 个回答
这影响很多事情。管理器的默认名称是 objects
,这只是一个默认值,并不是必须的。如果你在模型定义中没有包含 objects
,而是把管理器定义为 all_objects
,那么 ModelA.objects
就不存在了。Django 只是给模型分配了一个默认的管理器,如果模型中没有其他管理器,并且你自己没有定义 objects
。
总之,Django 会把模型中定义的第一个管理器称为“默认管理器”,并在需要引用模型的管理器时使用这个“默认”管理器(因为它不能简单地使用 objects
,因为 objects
可能没有被定义)。
一个简单的规则是,Django 应该使用的标准管理器(也就是说,最常用的管理器)应该是第一个定义的,不管它是分配给 objects
还是其他名称。其他的管理器应该在它之后定义。
如果你查看 get_object_or_404
的实现方式,你会发现它使用了模型的 _default_manager
属性,这就是 Django 用来指代第一个遇到的管理器的方式。(据我所知,所有 Django 的内部工作都是这样 -- 它们从不使用 Model.objects
等,因为你不应该假设默认管理器就叫 objects
)