I have working version without api, filling table with loop in templates. Works as i need, but because there is thousands rows of data, page loading 5-20 seconds. So i want use server side pagination. Problem is - bootstrap-table script generates url like this for example:
/api/parcels/?search=&sort=Size&order=desc&offset=0&limit=25&multiSort[0][sortName]=Price&multiSort[0][sortOrder]=asc&multiSort[1][sortName]=Region&multiSort[1][sortOrder]=asc
bootstrap-table.js can sort by single column, also have extension for multiple column sort, and own pagination.
Probably best way is to rewrite JS more into format of DRF. But i want do it opposite way, at least to get more experience with DRF.
So, i know DRF have own ordering accodring docs:
http://example.com/api/users?ordering=account,username
ordering_fields = ['account', 'username']
and with ORDERING_PARAM you can change name for query param. But format offered by bootstrap-table.js not fits at all. So question is - is there a way to change DRF ordering according to my needs and which is better way?
Just in case, my view and serializer so far.
class ParcelViewSet(generics.ListAPIView):
serializer_class = ParcelSerializer
def get_queryset(self):
queryset = Parcels.objects.all()
return queryset
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True)
response_data = {
"total": len(serializer.data),
"totalNotFiltered": len(serializer.data),
'rows': serializer.data
}
return Response(response_data)
class ParcelSerializer(serializers.ModelSerializer):
class Meta:
model = Parcels
fields = '__all__'
This way it works for me just fine. First check if there is sort param, so we make sure if user sorting by single or multiple columns.
Now need to figure out same for pagination :)
class CustomOrderFilter(OrderingFilter):
def get_ordering(self, request, queryset, view):
sort = request.query_params.get('sort')
if sort:
order = request.query_params.get('order')
ordering = ['-'+sort if order == 'desc' else sort]
return ordering
order_fields_bt = [v for k, v in request.query_params.items() if 'sortName' in k]
if order_fields_bt:
order_direction_bt = [v for k, v in request.query_params.items() if 'sortOrder' in k]
ordering = [''+order_fields_bt[i] if d == 'asc' else '-'+order_fields_bt[i] for i, d in enumerate(order_direction_bt)]
return ordering
# No ordering was included, or all the ordering fields were invalid
return self.get_default_ordering(view)