Django中的模型管理器 - 没有模型类的引用?
我在理解Django 1.6中的modelManager时遇到了困难。
我不明白这个代码是怎么工作的,哪里有“魔法”呢?
在get_queryset(self)这个方法里,根本没有提到Book类,那DahlBookManager是怎么知道它需要处理Book实例的呢?在调用super(DahlBookManager, self)的时候,既没有提到Book模型,按照我所知道的,self指的是一个"DahlBookManager"类型的对象,而不是Book。
所以,要么这里有某种“魔法”,要么我真的需要重新复习一下Python基础知识。
如果有人能帮我解答一下,我会很感激,谢谢!
# First, define the Manager subclass.
class DahlBookManager(models.Manager):
def get_queryset(self):
return super(DahlBookManager, self).get_queryset().filter(author='Roald Dahl')
# Then hook it into the Book model explicitly.
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
objects = models.Manager() # The default manager.
dahl_objects = DahlBookManager() # The Dahl-specific manager.
1 个回答
当你在Django中创建一个模型类时,它会对模型中的每个属性调用一个叫做 add_to_class
的方法。
https://github.com/django/django/blob/1.6.5/django/db/models/base.py#L143
如果你要添加的类有一个叫 contribute_to_class
的方法,那么就会调用这个方法,而不是使用 setattr
。
https://github.com/django/django/blob/1.6.5/django/db/models/base.py#L264
所以,当你用下面的代码把管理器分配给模型类时:
dahl_object = DahlBookManager()
管理器类会调用 contribute_to_class()
,并接收模型类。它会把这个模型类保存在 self.model
中:
https://github.com/django/django/blob/1.6/django/db/models/manager.py#L69
接着, get_queryset()
方法会使用这个 self.model
的引用:
https://github.com/django/django/blob/1.6/django/db/models/manager.py#L123