Diman
Diman

Reputation: 418

Django REST "GET" query params serializer

I want to receive get query and filter dataset with query params (if present). I'm currently using dumb method listed below. In this case I don't like the fact it's not checking that dates is actually could be parsed. In another method I may want to receive only numeric string which could be parsed to int. Is there some cool pythonic way to do it without writing a bunch of boilerplate code?

class TrackList(APIView):

    @token_required
    def get(self, request, pk, **kwargs):
        # read query params
        date_from = self.request.query_params.get('date_from')
        date_to = self.request.query_params.get('date_to')
        # if present then filter
        if date_from and date_to:
            points = Track.objects.filter(user_id=pk, date__range=[date_from, date_to])
        # otherwise don't filter
        else:
            points = Track.objects.filter(user_id=pk)
        points.order_by('date')
        serializer = TrackListSerializer(points, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

UPD: The question is not actually about dateutil.parser, it is about general query params parser. Maybe I should use Django rest serializers?

Upvotes: 2

Views: 5787

Answers (1)

anjaneyulubatta505
anjaneyulubatta505

Reputation: 11665

I think for above case we have to use the package django-filter. To install it pip install django-filter and its better to use Generic Views.

  1. add below code in settings.py

     REST_FRAMEWORK = {
       'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
     }
    
  2. working with views & filters

     from rest_framework import generics
     from django_filters import rest_framework as filters
     from myapp import Track    
    
     class TrackFilter(filters.FilterSet):
         from_date = filters.DateFilter(field_name="date", lookup_expr='gte')
         to_date = filters.DateFilter(field_name="date", lookup_expr='lte')
    
         class Meta:
           model = Track
           fields = ['date']
    
     class TrackListAPIView(generics.ListAPIView):
       queryset = Track.objects.all()
       serializer_class = TrackListSerializer
       filter_backends = (DjangoFilterBackend,) # optional
       filterset_class = TrackFilter
    

Usage:

http://localhost:8000/api/endpoint/?from_date=2018-01-01&to_date=2018-01-18

References:
http://django-filter.readthedocs.io/en/latest/ref/filterset.html
http://www.django-rest-framework.org/api-guide/filtering/

Upvotes: 5

Related Questions