Quasar Table组件非常优秀。数据量小的时候,可以直接一把读过来,让前端完成分页排序等操作。但数据量很大时(超过1000),则需要跟后端配合,按需加载。这里记录一下Django跟Quasar Table 这对最佳组合的使用方法。
前端 Quasar Table 的配置
- 配置属性对象
v-model:pagination="pagination"
,只要这个pagination
对象包含rowsNumber
属性,就代表需要服务端完成分页。 - 注册
@request
事件,一旦分页器(包括排序、过滤、每页个数)发生变化时,会触发该事件。 - 最好配置
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
- 重载分页器
PageNumberPagination
, 使page_size_query_param = 'rowsPerPage'
,这样可以跟Quasar匹配。 - 根据
q
的值的不同,完成后端数据库的检索。 - 根据
sortBy
和descending
, 完成数据排序。 - 返回分页数据。
核心代码
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)
注意点

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