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
posted @ 2020-07-27 20:58  lxttt521  阅读(175)  评论(0编辑  收藏  举报