drf内置排序源码
如果我们要用排序,那么写的视图类就必须直接或间接继承ListModelMixin,因为其内部有帮我们排序的放方法
ListModelMixin
# 调用了视图类对象的filter_queryset方法
queryset = self.filter_queryset(self.get_queryset())
但是我们视图类本身没有,根据orm查找顺序,我们就要看第一位父类
最后找到GenericAPIView的filter_queryset方法
def filter_queryset(self, queryset):
# filter_backends就是我们在视图类中写的drf内置的排序类
for backend in list(self.filter_backends):
# 实例化排序类对象,并调用它的filter_queryset方法
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
# 视图类中我们是这样设置的
filter_backends = [OrderingFilter]
OrderingFilter的filter_queryset方法
def filter_queryset(self, request, queryset, view):
# 调用了自己的get_ordering方法返回值应到是原本的queryset对象
ordering = self.get_ordering(request, queryset, view)
if ordering:
# 下面是得到ordering的方法,返回的结果是('id', 'price'),直接通过这个排序
return queryset.order_by(*ordering)
return queryset
OrderingFilter的get_ordering方法
def get_ordering(self, request, queryset, view):
# ordering_param是在drf的配置文件中的字符串:ordering
# params就是从url后ordering跟的排序字符串
# params:‘id,name,price’
params = request.query_params.get(self.ordering_param)
if params:
# 通过一个列表生成式得到['id','name','price']
fields = [param.strip() for param in params.split(',')]
# 通过内部remove_invalid_fields去移除fields中和视图类中设置不匹配的
# 视图类是这样设置的ordering_fields = ('id', 'price')
# 所以这里name是无效排序,就会通过这个方法移除
ordering = self.remove_invalid_fields(queryset, fields, view, request)
if ordering:
return ordering