我有一个模型和一个相应的模型管理器:
class MyModelManager(models.Manager):
def get(self, **kwargs):
return super().select_related('group').get(**kwargs)
class MyModel(models.Model):
name = models.CharField(...)
group = models.ForeignKey('Group', ...)
tags = models.ManyToManyField('Tag', ...)
# ... others ...
objects = MyModelManager()
模型管理器在select_related()
例程中执行get()
,以便始终连接给定的外键字段(我可能会经常引用它)。当我调用get()
例程时,事情按预期运行:
obj = models.MyModel.objects.get(pk=1)
print(obj.group) # Doesn't hit the database a second time
但是,如果我拨打类似prefetch_related()
之类的电话,则我的自定义管理器会被丢弃:
obj = models.MyModel.objects.prefetch_related('tags').get(pk=1)
print(obj.group) # Hits the database a second time to get the group
当我打印类型时,原因就很清楚了
x = models.MyModel.objects
print(type(x)) # Yields <class 'base.models.TestCaseManager'>
y = models.MyModel.objects.prefetch_related('tags')
print(type(y)) # Yields <class 'django.db.models.QuerySet'>
我可以通过链式调用返回我的自定义管理器实例,而不是默认实例吗?
答案 0 :(得分:1)
模型管理器的API定义显式返回QuerySet
对象,而不返回管理器对象。假设管理器已正确实现,返回的QuerySet
仍具有管理器的所有自定义设置。 prefetch_related
没什么特别的,filter
,all
,none
,annotate
等也是如此。基本上,管理器对象是{的生成器{1}}个对象以及许多QuerySet
方法也是QuerySet
对象的生成器。调用生成QuerySet
的方法后,您不应期望能够调用诸如get_or_create
之类的特定于管理器的方法。