Django不同QuerySet调用返回结果一致,加all()和不加有何区别?
两种Django模型查询写法的核心差异
核心结论
这两种写法在常规使用场景下没有任何功能、性能差异,返回的结果、执行的SQL语句完全一致。
底层逻辑说明
- Django的模型管理器
ModelManager(也就是你调用的Post.objects)本身不实现查询逻辑,它的filter、order_by、exclude等查询方法,都是对底层QuerySet对应方法的代理:你直接调用Post.objects.filter(xxx)时,管理器内部会先隐式调用一次all()拿到基础QuerySet实例,再在这个实例上执行后续的过滤操作。 - 你手动添加
all()的写法,只是把管理器隐式执行的步骤显式写了出来,不会改变最终生成的查询逻辑。
唯一存在差异的场景
只有当你自定义了模型管理器,且没有为自定义QuerySet的方法做管理器代理时,才会需要显式调用all():
比如你定义了如下自定义QuerySet和管理器:
class PostQuerySet(models.QuerySet): def published(self): return self.filter(status=1) class PostManager(models.Manager): pass # 没有代理PostQuerySet的published方法 class Post(models.Model): # ...字段定义 objects = PostManager()
这种场景下你无法直接调用Post.objects.published(),但可以通过Post.objects.all().published()拿到QuerySet后调用自定义的查询方法。
关于可读性的说明
你习惯显式加all()提升可读性的写法完全合理,不会带来额外的性能开销:Django的QuerySet是惰性执行的,只要没有触发求值操作(迭代、切片、转列表、调用first()/count()等),中间的链式调用只会生成临时的QuerySet实例,资源消耗可以忽略不计。
你也可以通过打印QuerySet的query属性验证二者生成的SQL完全一致:
print(Post.objects.filter(status=1).order_by('-updated').query) print(Post.objects.all().filter(status=1).order_by('-updated').query)
内容的提问来源于stack exchange,提问作者Kentypop
相关产品推荐
相关产品推荐

