美文网首页
Django REST framework 分页 与 Quasa

Django REST framework 分页 与 Quasa

作者: alue | 来源:发表于2022-05-22 22:59 被阅读0次

Quasar Table组件非常优秀。数据量小的时候,可以直接一把读过来,让前端完成分页排序等操作。但数据量很大时(超过1000),则需要跟后端配合,按需加载。这里记录一下Django跟Quasar Table 这对最佳组合的使用方法。

前端 Quasar Table 的配置

  1. 配置属性对象 v-model:pagination="pagination" ,只要这个 pagination 对象包含 rowsNumber 属性,就代表需要服务端完成分页。
  2. 注册@request 事件,一旦分页器(包括排序、过滤、每页个数)发生变化时,会触发该事件。
  3. 最好配置 loading ,给用户视觉提示。

核心代码


// 分页  
const pagination = ref({  
  sortBy: undefined,  
  descending: undefined,  
  rowsNumber: undefined,  
  page: 1,  
  rowsPerPage: 15,  
});

onMounted(async () => {  
  await onRequest({  
    pagination: pagination.value,  
    filter: undefined,  
  });  
});
const rows = ref([]);  
const loading = ref(false);  
const filter = ref("");

async function onRequest(props) {  
  loading.value = true;  
  const data = await api.get(URLs.leaveHistory, {  
    params: {  
      ...props.pagination,  
      descending: props.pagination.descending ? 0 : 1,  
      q: props.filter,  
    },  
  });  
  
  if (props.pagination.rowsPerPage === 0) {  
    rows.value = data;  
  } else {  
    rows.value = data.results;  
  }  
  
  loading.value = false;  
  pagination.value.sortBy = props.pagination.sortBy;  
  pagination.value.descending = props.pagination.descending;  
  pagination.value.page = props.pagination.page;  
  pagination.value.rowsPerPage = props.pagination.rowsPerPage;  
  pagination.value.rowsNumber = data.count;  
}

后端 Django REST framework

  1. 重载分页器 PageNumberPagination , 使 page_size_query_param = 'rowsPerPage' ,这样可以跟Quasar匹配。
  2. 根据 q 的值的不同,完成后端数据库的检索。
  3. 根据 sortBydescending , 完成数据排序。
  4. 返回分页数据。

核心代码

class MyPageNumberPagination(PageNumberPagination):  
    page_size_query_param = 'rowsPerPage'  # items per page  
    page_size = 15  
    max_page_size = 100

class LeaveViewSet(viewsets.ModelViewSet):  
    serializer_class = serializers.LeaveSerializer  
    pagination_class = MyPageNumberPagination

    @action(detail=False, methods=['get'])  
    def history(self, request):  
        """ 全部历史请假记录 """    
        qs = self.get_queryset()  
        q = self.request.GET.get('q', None)  

        sortBy = self.request.GET.get('sortBy', None)  
        descending = self.request.GET.get('descending', 0)  
        rowsPerPage = self.request.GET.get('rowsPerPage', 0)  
  
        if q is not None:  
            qs = qs.filter(  
                Q(student__name__contains=q) |  
                Q(student__pinyin__contains=q) |  
                Q(student__pinyin_shortcut__startswith=q)  
            )  
        if sortBy is not None:  
            prefix = '-' if int(descending) else ''  
            qs = qs.order_by(prefix + sortBy)  
      
        page = self.paginate_queryset(qs)  
        if page is not None and int(rowsPerPage) > 0:  
            serializer = self.get_serializer(page, many=True)  
            return self.get_paginated_response(serializer.data)  
      
        serializer = self.get_serializer(qs, many=True)  
        return Response(serializer.data)


注意点

  1. Quasar Table 组件的分页器,有一个‘全部’选项,点击后,传给后端的rowsPerPage为0,Django需要为此做单独的判断。
  2. 默认情况下,Django收到前端传来的 descending 是字符串形式的'false' 和 'true',如果直接用 if descending 来做判断,条件永远都是True. 这里特别要小心。
  3. 如果排序字段特别多,每个还都有正负两种情况,后端会充斥着if else。 可以参考这种方式,统一处理:
prefix = '-' if int(descending) else ''  
queryset = queryset.order_by(prefix + sortBy)

相关文章

网友评论

      本文标题:Django REST framework 分页 与 Quasa

      本文链接:https://www.haomeiwen.com/subject/cnplprtx.html