Search code examples
pythondjangodjango-filter

I have troubles while filtering by year and month in Django


I'm trying to filter queryset by month and date

Here is a code:

class FinalListView(generics.ListAPIView):
    serializer_class = FinalSerializer
    filter_backends = [django_filters.rest_framework.DjangoFilterBackend]

    def get_queryset(self):
        condition = Q()
        queryset = Final.objects.all()
        month = self.request.query_params.getlist('month')
        year = self.request.query_params.getlist('year')

    if month:
        if month != 'all':
            for a in month:
                condition |= Q(created_at__month=a)
            queryset = queryset.filter(condition)
            print (queryset)
    if year:
        if year != 'all':
            for a in year:
                condition |= Q(created_at__year=a)
            queryset = queryset.filter(condition)
            print (queryset)
            
        
    return queryset

When I'm filtering by year, it returns 200 response, but 0 objects

When I'm filtering by month, I can't even get a 200 response, it returns 500 response


Solution

  • As stated in docs getlist returns a list (in your case of all months or years which are supplied in url).

    You can use __in to filter by a list of values.

    With that in mind you can try this:

    class FinalListView(generics.ListAPIView):
        serializer_class = FinalSerializer
        filter_backends = [django_filters.rest_framework.DjangoFilterBackend]
    
        def get_queryset(self):
            queryset = Final.objects.all()
            months = self.request.query_params.getlist('month')
            years = self.request.query_params.getlist('year')
    
            if months and 'all' not in months:
                queryset = queryset.filter(created_at__month__in=months)
                print (queryset)
            if years and 'all' not in years:
                queryset = queryset.filter(created_at__year__in=years)
                print (queryset)
    
        return queryset
    

    Send requests like so: GET /final/?month=1, GET /final/?year=2020, ...