Как заставить упорядочивание и фильтрацию DRF работать с пользовательскими query_params, которые генерируются расширением bootstrap-table

У меня есть рабочая версия без api, заполнение таблицы с помощью цикла в шаблонах. Работает как мне нужно, но поскольку там тысячи строк данных, загрузка страницы 5-20 секунд. Поэтому я хочу использовать пагинацию на стороне сервера. Проблема в том, что скрипт bootstrap-table генерирует url, например, такой:

/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 может сортировать по одной колонке, также есть расширение для сортировки по нескольким колонкам и собственная пагинация.

Возможно, лучший способ - это переписать JS в формат DRF. Но я хочу сделать это наоборот, по крайней мере, чтобы получить больше опыта работы с DRF.

Итак, я знаю, что у DRF есть собственное упорядочивание в соответствии с документами:

http://example.com/api/users?ordering=account,username

.

orderering_fields = ['account', 'username']

и с помощью ORDERING_PARAM вы можете изменить имя параметра запроса. Но формат, предлагаемый bootstrap-table.js, совсем не подходит. Поэтому вопрос - есть ли способ изменить упорядочивание DRF в соответствии с моими потребностями и какой способ лучше?

На всякий случай, мое представление и сериализатор на данный момент.

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__'

Этот способ работает для меня просто отлично. Сначала проверяем, есть ли параметр sort, чтобы убедиться, сортирует ли пользователь по одному или нескольким столбцам.

Теперь нужно придумать то же самое для пагинации :)

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)
Вернуться на верх