【问题标题】:Filter for Multiple values of a field in DRF过滤 DRF 中字段的多个值
【发布时间】:2020-11-03 14:05:02
【问题描述】:

在亚马逊中,您可以按多个品牌进行过滤,例如。你选择耐克、彪马、阿迪达斯。发回的查询集包含属于这些品牌中的任何一个的产品。

如果你有这样的模型:

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=[耐克、阿迪达斯、彪马]

提前致谢!!!!

【问题讨论】:

标签: django django-rest-framework django-filter


【解决方案1】:

multiple choice 的正常行为类似于 ?f=v1&f=v2,而您可以传递正确的 widget 以使用 CSVWidget 将默认 url 结构更改为逗号分隔值

from django_filters.fields import CSVWidget

class ProductMultipleFilterBackend(df_filters.FilterSet):
    brand = MultipleFilter(
                 lookup_expr="icontains", 
                 field_name = "brand",
                 widget=CSVWidget
            )
     ...

然后,您可以使用 csv 格式进行过滤,例如:url?brand=a,b

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-23
    • 2021-10-20
    • 2015-12-15
    • 2021-12-30
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 2023-01-09
    相关资源
    最近更新 更多