slurms
slurms

Reputation: 768

How to paginate with filters in django rest framework

I currently have an API view setup as follows:

class WeatherObservationSerializer(serializers.ModelSerializer):
    dew_point = serializers.Field(source='dew_point')
    wind_gust = serializers.Field(source='get_wind_gust')

    class Meta:
        model = WeatherObservation
        fields = ('id', 'station', 'temperature', 'pressure', 'humidity',
                  'wind_direction', 'wind_speed', 'rainfall', 'date',
                  'dew_point', 'wind_gust')

class WeatherObservationList(generics.ListCreateAPIView):
    model = WeatherObservation
    serializer_class = WeatherObservationSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def get_queryset(self):
        queryset = WeatherObservation.objects.all()
        min_date = self.request.QUERY_PARAMS.get('min_date', None)
        station = self.request.QUERY_PARAMS.get('station', None)
        if min_date is not None:
            queryset = queryset.filter(date__gte=min_date)
        if station is not None:
            queryset = queryset.filter(station=station)
        return queryset

My settings.py contains: REST_FRAMEWORK = { 'PAGINATE_BY': 50, 'PAGINATE_BY_PARAM': 'page' }

When I make a request to the API like so: /api/weather/observations/?station=2&page=2&min_date=2013-3-14 I only get back two results. If it's for page 3, 3 results, and so on. Is there anything I'm doing wrong that is causing this problem?

Cheers.

Upvotes: 11

Views: 11763

Answers (3)

Ashish Sondagar
Ashish Sondagar

Reputation: 1095

Use filter-and-pagination plugin. Is well handling Filter & Pagination feature

pip install filter-and-pagination

Upvotes: 0

nexla
nexla

Reputation: 453

Not sure how helpful that would be, but I needed to paginate a single view in my project that uses filter. what i did was

class GlobalFilter(CustomMixin):

    from rest_framework.pagination import PageNumberPagination

    queryset = Data.objects.all()
    filter_backends = [DjangoFilterBackend]
    serializer_class = FilterSerializer
    filterset_class = GlobalFilterSet
    pagination_class = PageNumberPagination
    pagination_class.page_size = 100

Could be helpful for someone else maybe :)

Upvotes: 2

Hamms
Hamms

Reputation: 5107

Check out the docs for those settings:

PAGINATE_BY_PARAM

The name of a query parameter, which can be used by the client to overide the default page size to use for pagination. If set to None, clients may not override the default page size.

Simply remove that line from your settings.py and you should be fine.

UPDATE 1/7/2016:

Note that this setting is now in the process of deprecation. You can consult the pagination guide for more details.

The short version is that you should now create a custom Pagination class with the appropriate settings which you then apply to your view. The examples in linked guide should be more than helpful.

Upvotes: 6

Related Questions