在 Django Rest Framework 中过滤多个值
Filter on multiple values in Django Rest Framework
我有一个模型,我想过滤多个值。
我的模特:
class Product(models.Model):
ean = models.CharField(max_length=13, unique=True)
product_id = models.CharField(max_length=20, null=True, blank=True)
product_image = models.URLField(max_length=300, null=True, blank=True)
product_title = models.CharField(max_length=300, null=True, blank=True)
我想在 'ean' 字段或主键上进行过滤,两者都可以。在我当前的设置下,我只能看到最后一个值。例如,当我将 URL 构造为 www.example.com/api/Product/?id=1&id=2 时,我只能看到 ID 为 2 的产品,而我想看到 ID 为 1 和 ID 为 2 的产品。
我应该如何构建我的 ViewSet?
目前我有:
class ProductViewSet(ModelViewSet):
queryset = models.Product.objects.all()
serializer_class = serializers.ProductSerializer
filter_backends = [DjangoFilterBackend]
filter_fields = ('id','ean')
您可以在 views.py
中尝试类似的操作,并在参数中传递密钥 id
和 ean
。请注意,您必须在参数中将多个值作为逗号分隔值传递。
class ProductViewSet(APIView):
def get(self, request):
_id = self.request.GET.get('id', None).split(',')
ean = self.request.GET.get('ean', None).split(',')
qs = Product.objects.filter(Q(id__in=_id) | Q(ean__in=ean))
data = serializers.ProductSerializer(qs, many=True, context={'request': request}).data
if data:
return Response({
'message': 'success',
"data":data,
},status=200)
else:
return Response({
'message':'no data available',
'success':'False'
},status=200)
有一种更简单的方法可以使用 django-filter
package. Deep within the django-filter
documentation 实现此目的,它提到您可以使用“映射到查找列表的字段名称字典”。
您的代码将像这样更新:
# views.py
from django_filters.rest_framework import DjangoFilterBackend
class ProductViewSet(ModelViewSet):
queryset = models.Product.objects.all()
serializer_class = serializers.ProductSerializer
filter_backends = [DjangoFilterBackend]
filter_fields = {
'id': ["in", "exact"], # note the 'in' field
'ean': ["exact"]
}
现在,在 URL 中,您可以在提供参数列表之前将 __in
添加到过滤器,它会按您预期的那样工作:
www.example.com/api/Product/?id__in=1,2
关于查找过滤器可用的 django-filter
文档很差,但是 in
查找过滤器在 Django documentation 本身中提到。
我有一个模型,我想过滤多个值。
我的模特:
class Product(models.Model):
ean = models.CharField(max_length=13, unique=True)
product_id = models.CharField(max_length=20, null=True, blank=True)
product_image = models.URLField(max_length=300, null=True, blank=True)
product_title = models.CharField(max_length=300, null=True, blank=True)
我想在 'ean' 字段或主键上进行过滤,两者都可以。在我当前的设置下,我只能看到最后一个值。例如,当我将 URL 构造为 www.example.com/api/Product/?id=1&id=2 时,我只能看到 ID 为 2 的产品,而我想看到 ID 为 1 和 ID 为 2 的产品。
我应该如何构建我的 ViewSet? 目前我有:
class ProductViewSet(ModelViewSet):
queryset = models.Product.objects.all()
serializer_class = serializers.ProductSerializer
filter_backends = [DjangoFilterBackend]
filter_fields = ('id','ean')
您可以在 views.py
中尝试类似的操作,并在参数中传递密钥 id
和 ean
。请注意,您必须在参数中将多个值作为逗号分隔值传递。
class ProductViewSet(APIView):
def get(self, request):
_id = self.request.GET.get('id', None).split(',')
ean = self.request.GET.get('ean', None).split(',')
qs = Product.objects.filter(Q(id__in=_id) | Q(ean__in=ean))
data = serializers.ProductSerializer(qs, many=True, context={'request': request}).data
if data:
return Response({
'message': 'success',
"data":data,
},status=200)
else:
return Response({
'message':'no data available',
'success':'False'
},status=200)
有一种更简单的方法可以使用 django-filter
package. Deep within the django-filter
documentation 实现此目的,它提到您可以使用“映射到查找列表的字段名称字典”。
您的代码将像这样更新:
# views.py
from django_filters.rest_framework import DjangoFilterBackend
class ProductViewSet(ModelViewSet):
queryset = models.Product.objects.all()
serializer_class = serializers.ProductSerializer
filter_backends = [DjangoFilterBackend]
filter_fields = {
'id': ["in", "exact"], # note the 'in' field
'ean': ["exact"]
}
现在,在 URL 中,您可以在提供参数列表之前将 __in
添加到过滤器,它会按您预期的那样工作:
www.example.com/api/Product/?id__in=1,2
关于查找过滤器可用的 django-filter
文档很差,但是 in
查找过滤器在 Django documentation 本身中提到。