django-rest-framework- 使用“或”过滤来自一个 url 参数的多个值

我为我的 API 公开的模型设置了一个标记系统。模型看起来像这样:


class TaggableModel(models.Model):

    name = models.CharField(max_length=255)

    tags = models.ManyToManyField(Tag, related_name="taggable_models")


class Tag(models.Model):

    tag = models.CharField(max_length=32)

然后我设置了一个序列化程序并查看如下所示:


class TaggableModelSerializer(serializers.ModelSerializer):

    class Meta:

        model = TaggableModel

        fields = ('id', 'name', 'tags',)

        read_only_fields = ('id',)


class TaggableModelViewSet(viewsets.ModelViewSet):

    queryset = TaggableModel.objects.all()

    serializer_class = TaggableModelSerializer

    permission_classes = (AllowAny,)

    filter_backend = [DjangoFilterBackend]

    filterset_fields = ['tags']

如果我想获取所有TaggableModels标签 ID 为 1、2 或 3 的内容,可以通过以下方式进行:


https://my-api-domain/api/taggable-models?tags=1&tags=2&tags=3


有没有办法在分隔符上拆分,所以我可以将它全部作为一个参数传递?例如:


https://my-api-domain/api/taggable-models?tags=1,2,3


看起来我可以编写自己的自定义 DjangoFilterBackend 过滤器,但我有点不确定从哪里开始。或者也许有更简单的方法来实现这一点?


人到中年有点甜
浏览 121回答 2
2回答

largeQ

当然,您可以通过使用具有特定字段“小部件”的自定义过滤器集类来做到这一点(这就是它在 django-filters 中的调用方式)这是您可以尝试的示例:# filters.pyfrom django_filters.rest_framework import FilterSet, filtersfrom django_filters.widgets import CSVWidgetfrom .your_models import Tag, TaggableModelclass TaggableModelFilterSet(FilterSet):    tags = filters.ModelMultipleChoiceFilter(        queryset=Tag.objects.all(), widget=CSVWidget,        help_text=_("A list of ids, comma separated, identifying tags"),        method='filter_tags'    )    class Meta:        model = TaggableModel        fields = ['tags']    def filter_tags(self, queryset, name, value):        if value:            queryset = queryset.filter(tags__in=value)        return queryset# views.pyclass TaggableModelViewSet(viewsets.ModelViewSet):    queryset = TaggableModel.objects.all()    serializer_class = TaggableModelSerializer    permission_classes = (AllowAny,)    filter_backends = [DjangoFilterBackend]    filter_class = TaggableModelFilterSet

30秒到达战场

django-filter使用package有一种更简单的方法来实现这一点。django-filter在文档的深处,它提到您可以使用“映射到查找列表的字段名称字典”。您的代码将像这样更新:# views.pyfrom django_filters.rest_framework import DjangoFilterBackendclass TaggableModelViewSet(viewsets.ModelViewSet):    queryset = TaggableModel.objects.all()    serializer_class = TaggableModelSerializer    permission_classes = (AllowAny,)    filter_backend = [DjangoFilterBackend]    filterset_fields = {        'tags': ["in", "exact"] # note the 'in' field    }现在在 URL 中,您将__in在提供参数列表之前添加到过滤器中,它会按预期工作:https://my-api-domain/api/taggable-models?tags__in=1,2,3关于哪些查找过滤器可用的django-filter文档非常差,但是在Django 文档本身in中提到了查找过滤器。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python