代码中super(CommentManager, self)的使用疑问:能否用instance替代?
super(CommentManager, self),能不能用instance.filter()替代? 哎,这个问题问到点子上了,咱们掰开揉碎了说:绝对不能用instance.filter()替代super(...),核心原因在于这两行代码的操作对象完全不是一回事:
1. super(CommentManager, self).filter()的本质
你定义的CommentManager是继承自Django的models.Manager,它的职责就是专门管理Comment模型的数据库操作。super(CommentManager, self)的作用是获取父类(也就是原生的models.Manager)的实例,然后调用它的filter方法——这个filter是针对Comment数据表的查询,用来筛选符合条件的Comment对象。
原代码的逻辑很明确:通过ContentType识别传入的instance所属的模型类型,再结合instance.id,找出所有关联到这个instance、且没有父评论的Comment,全程都是在操作Comment表的数据。
2. instance.filter()为啥完全行不通?
instance是你传入的另一个模型的实例(比如可能是Post、Article这类需要关联评论的模型),它的filter方法属于该实例所属模型的管理器。举个例子,如果instance是Post的实例,instance.filter()等价于Post.objects.filter()——这是在查询Post表的数据,和Comment表没有任何关系!
你本来要找的是关联到这个Post的Comment,改成instance.filter()后,反而变成了去查Post表中满足content_type=xxx, object_id=xxx的Post,逻辑完全跑偏,根本得不到你想要的评论数据。
一句话总结
super(...)是调用Comment模型管理器的查询方法,操作的是Comment表;instance.filter()是操作传入实例所属模型的表,和目标Comment表无关,完全达不到需求。
内容的提问来源于stack exchange,提问作者DeepRockWeb

