Wykonałem punkt końcowy API przy użyciu ram do odpoczynku Django, można go przesączyć według dwóch parametrów. Próbuję wykonać następujące czynności: Gdy nie ma filtra, powinien odzyskać x liczbę rekordów, podczas gdy gdy jest jeden lub więcej filtra, musi odzyskać więcej rekordów. Zasadniczo muszę zmienić paginację, jeśli są filtry.

Oto, czego próbowałem:

class My_View(viewsets.ModelViewSet):
    http_method_names = ['get']
    serializer_class = My_Serializer
    pagination_class = StandardResultsSetPagination

    def get_queryset(self):

        valid_filters = {
            'Name': 'Name',
            'Date': 'Unix__gte',
        }

        filters = {valid_filters[key]: value for key, value in self.request.query_params.items() if key in valid_filters.keys()}

        if len(filters) == 0:
            pagination_class = StandardResultsSetPagination
        else:
            pagination_class = LargeResultsSetPagination

        queryset = My_Model.objects.filter(**filters)

        return queryset

Jaki powinien to zrobić, to ustawić standardowe paginację 100, jeśli nie ma filtra i 200, jeśli są filtry.

Ten kod nie działa, paginacja zawsze będzie ustawiona na StandardResultsSetPagination i nie zostanie zmieniona. Myślę, że jest to dlatego, że get_queryset jest wywoływana po ustawieniu paginacji, więc nie można go ponownie ustawić później. Czy istnieje jakiś sposób, aby to zrobić? Z góry dziękuję!

2
JayK23 20 październik 2020, 00:49

1 odpowiedź

Najlepsza odpowiedź

Będziesz musiał zastąpić metodę get_page_size klasy paginacji:

from rest_framework.pagination import LimitOffsetPagination

valid_filters = {'Name', 'Date'}
def _has_valid_filters(iterable):
    return not valid_filters.isdisjoint(iterable)

class MyPagination(LimitOffsetPagination):
    def get_page_size(self, request):
        if _has_valid_filters(request.query_params.items()):
            return 200
        else:
            return 100

class MyView(viewsets.ModelViewSet):
    pagination_class = MyPagination
    ...
1
Elrond Supports Monica 20 październik 2020, 00:08