关于Django中get_queryset方法的*args、**kwargs作用及替代写法的疑问
关于get_queryset方法中*args和**kwargs的作用及写法对比
原代码示例
queryset = MyModel.objects.all() get_queryset(self, *args, **kwargs): return (super().get_queryset(*args, **kargs).order_by(self.name))
疑问中的替代写法
get_queryset(self): return MyModel.objects.order_by(self.name)
一、*args和**kwargs的作用
- 兼容参数传递:
*args用来接收任意数量的位置参数,**kwargs用来接收任意数量的关键字参数。调用父类get_queryset时带上这俩,能确保父类方法需要的所有参数都被完整传递,避免因为父类方法签名变更(比如框架版本更新新增参数)导致代码报错,提升兼容性。 - 继承父类逻辑:父类的
get_queryset可能包含通用处理逻辑(比如权限过滤、默认条件筛选),通过传递参数调用父类方法,能让这些逻辑正常执行,再基于父类返回的查询集做后续排序操作。
二、为什么不采用替代写法?
- 跳过父类核心逻辑:直接调用
MyModel.objects.order_by(...)会完全绕开父类get_queryset中的处理逻辑。比如如果父类是Django通用视图里的get_queryset,它可能已经做了“只返回当前用户有权限查看的数据”这类过滤,替代写法会忽略这些规则,导致返回结果不符合预期。 - 破坏继承可维护性:用
super()调用父类方法是面向对象重写的标准做法,能保证父类后续的逻辑更新(比如新增过滤条件、优化查询性能)自动被子类继承,不用手动修改子类代码。 - 查询集来源不一致:原代码基于父类返回的查询集做排序,而替代写法直接从模型的objects创建新查询集,两者的初始查询集可能完全不同,最终结果自然会有差异。
内容的提问来源于stack exchange,提问作者Baz
相关产品推荐
相关产品推荐

