1

Is it someway to filter querysets with multiple optional parameters in Django more efficiently?

For ex. I have product list and user can filter it by using multiple GET params. 6 params in this case. Thanks.

class ProductList(ListAPIView):
    permission_classes = (IsAdminUser,)
    serializer_class = ProductSerializer

    def get_queryset(self):
        queryset = Product.objects.order_by('-created_at')
        category_id = self.request.GET.get('category_id')
        color = self.request.GET.get('color')
        size = self.request.GET.get('size')
        status = self.request.GET.get('status')
        date_from = self.request.GET.get('date_from')
        date_to = self.request.GET.get('date_to')
        if category_id:
            queryset = queryset.filter(category_id=category_id)
        if color:
            queryset = queryset.filter(color=color)
        if size:
            queryset = queryset.filter(size=size)
        if status:
            queryset = queryset.filter(status=sistatusze)
        if date_from:
            queryset = queryset.filter(created_at__gte=date_from)
        if date_to:
            queryset = queryset.filter(created_at__lte=date_to)
        return queryset

1 Answer 1

1

You can make a utility function that will not filter the conditions where the value is None:

def filter_if_not_none(qs, **kwargs):
    return qs.filter(**{k: v for k, v in kwargs.items() if v is not None})

then we can use this utility as:

class ProductList(ListAPIView):
    permission_classes = (IsAdminUser,)
    serializer_class = ProblemSerializer

    def get_queryset(self):
        queryset = Product.objects.order_by('-created_at')
        return filter_qs_if_not_none(
            queryset,
            category_id=self.request.GET.get('category_id')
            color=self.request.GET.get('color')
            size=self.request.GET.get('size')
            status=self.request.GET.get('status')
            created_at__gte=self.request.GET.get('date_from')
            created_at__lte=self.request.GET.get('date_to')
        )
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.