首页 > 解决方案 > 在 django 中使用多个参数过滤查询

问题描述

是否以某种方式更有效地过滤 Django 中具有多个可选参数的查询集?

例如。我有产品列表,用户可以使用多个 GET 参数对其进行过滤。在这种情况下有 6 个参数。谢谢。

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

标签: djangodjango-rest-frameworkdjango-views

解决方案


您可以制作一个不会过滤值为 的条件的实用程序函数None

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

然后我们可以将此实用程序用作:

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')
        )

推荐阅读