Python 自定义模型管理器被预回迁\u相关
我有一个模型和相应的模型管理器:Python 自定义模型管理器被预回迁\u相关,python,django,Python,Django,我有一个模型和相应的模型管理器: 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', ...
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()
模型管理器在get()
例程中执行一个select\u related()
,这样我就可以始终加入给定的外键字段(我可能会经常引用它)。当我调用get()
例程时,事情正如我所期望的那样工作:
obj = models.MyModel.objects.get(pk=1)
print(obj.group) # Doesn't hit the database a second time
但是,如果我调用类似于prefetch\u 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'>
x=models.MyModel.objects
打印(类型(x))#产量
y=models.MyModel.objects.prefetch_相关('tags'))
打印(类型(y))#产量
我的问题
我是否可以获取链接调用以返回自定义管理器实例,而不是默认实例?模型管理器的API定义明确返回
QuerySet
对象,而不是管理器对象。返回的QuerySet
仍然包含来自管理器的所有自定义设置,前提是管理器实现正确。与prefetch\u相关的在这里没有什么特别之处,同样的情况也发生在filter
、all
、none
、annotate
等方面。基本上,管理器对象是QuerySet
对象的生成器,许多QuerySet
方法也是QuerySet
对象的生成器。在调用生成查询集的方法后,您不应该期望能够调用特定于管理器的方法,如get\u或\u create
。我对调用第二个特定于管理器的方法不感兴趣,但我确实希望在get\u queryset()
中使用的select\u related()
调用保持不变。我真的不知道为什么它不是…它一直在。尝试执行print(y.query)
。因此select\u related()
实际上发生在管理器的get()
调用中(覆盖默认值)。现在我明白了,这回到了您最初的观点,即我不应该期望在获得queryset之后调用特定于管理器的方法(在本例中是我的自定义get()
函数)。这样的东西有更好的地方吗?这基本上是定制管理器的规范用例,定义了一个get\u queryset()
覆盖,它添加了特定的过滤、注释等。模型管理器的官方文档涵盖了很多内容: