在 DRF 中过滤一个字段的多个值
Filter for Multiple values of a field in DRF
在亚马逊中,您可以按多个品牌进行过滤,例如。你 select 耐克、彪马、阿迪达斯。发回的查询集包含属于这些品牌之一的产品。
如果您有这样的模型:
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
brand = models.CharField(max_length=100)
像这样的序列化器:
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = models.Product
fields = "__all__"
像这样的视图集:
class ProductViewSet(viewsets.ModelViewSet):
serializer_class = serializers.ProductSerializer
permission_classes = [IsAuthenticated]
filter_backends = [filters.ProductMultipleFilterBackend ]
filters.py 文件:
from rest_framework import filters as drf_filters
from django_filters import rest_framework as df_filters
class MultipleField(MultipleChoiceField):
def valid_value(self, value):
return True
class MultipleFilter(df_filters.MultipleChoiceFilter):
field_class = MultipleField
class ProductMultipleFilterBackend(df_filters.FilterSet):
brand = MultipleFilter(lookup_expr="icontains", field_name = "brand")
search = MultipleFilter(lookup_expr="icontains", field_name = "description")
class Meta:
model = models.Product
fields = ["brand", "search"]
上面的代码是我找到的 here。但它已经有 5 年历史了,可能有更好的方法我肯定不知道,我在代码中遇到以下错误:
filter_queryset() takes 2 positional arguments but 4 were given
这些请求的 url 结构是什么:
/someurl?brand=耐克,阿迪达斯,彪马
要么
/someurl?brand=[耐克、阿迪达斯、彪马]
提前致谢!!!!
multiple choice
的正常行为类似于 ?f=v1&f=v2
,而您可以通过适当的 widget
将默认 url 结构更改为逗号分隔值,方法是使用 CSVWidget
from django_filters.fields import CSVWidget
class ProductMultipleFilterBackend(df_filters.FilterSet):
brand = MultipleFilter(
lookup_expr="icontains",
field_name = "brand",
<b>widget=CSVWidget</b>
)
...
然后,您可以使用 csv 格式进行过滤,例如:url?brand=a,b
在亚马逊中,您可以按多个品牌进行过滤,例如。你 select 耐克、彪马、阿迪达斯。发回的查询集包含属于这些品牌之一的产品。
如果您有这样的模型:
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
brand = models.CharField(max_length=100)
像这样的序列化器:
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = models.Product
fields = "__all__"
像这样的视图集:
class ProductViewSet(viewsets.ModelViewSet):
serializer_class = serializers.ProductSerializer
permission_classes = [IsAuthenticated]
filter_backends = [filters.ProductMultipleFilterBackend ]
filters.py 文件:
from rest_framework import filters as drf_filters
from django_filters import rest_framework as df_filters
class MultipleField(MultipleChoiceField):
def valid_value(self, value):
return True
class MultipleFilter(df_filters.MultipleChoiceFilter):
field_class = MultipleField
class ProductMultipleFilterBackend(df_filters.FilterSet):
brand = MultipleFilter(lookup_expr="icontains", field_name = "brand")
search = MultipleFilter(lookup_expr="icontains", field_name = "description")
class Meta:
model = models.Product
fields = ["brand", "search"]
上面的代码是我找到的 here。但它已经有 5 年历史了,可能有更好的方法我肯定不知道,我在代码中遇到以下错误:
filter_queryset() takes 2 positional arguments but 4 were given
这些请求的 url 结构是什么: /someurl?brand=耐克,阿迪达斯,彪马 要么 /someurl?brand=[耐克、阿迪达斯、彪马]
提前致谢!!!!
multiple choice
的正常行为类似于 ?f=v1&f=v2
,而您可以通过适当的 widget
将默认 url 结构更改为逗号分隔值,方法是使用 CSVWidget
from django_filters.fields import CSVWidget
class ProductMultipleFilterBackend(df_filters.FilterSet):
brand = MultipleFilter(
lookup_expr="icontains",
field_name = "brand",
<b>widget=CSVWidget</b>
)
...
然后,您可以使用 csv 格式进行过滤,例如:url?brand=a,b