Django 过滤器 BaseInFilter

Django-filter BaseInFilter

我目前正在尝试使用 BaseInFilter。用户可以输入以逗号分隔的 ID,如图所示。我想做一个验证器(或规范用户的输入),让用户在这里只能输入整数。

如果用户输入字符,Django后台会抛出这个错误。

我也试过这个:

class BaseIntegerFilter(filters.BaseInFilter, filters.NumberFilter):
    pass

class HardwareFilter(filters.FilterSet):
    queryset = Hardware
    serializer_class = HardwareSerializer
    id = filters.BaseIntegerFilter(field_name="id", label="Comma separated list of hardware IDs", help_text="Comma separated list of hardware IDs")

但是这个解决方案不允许我再在文本框中输入逗号。

有人能帮忙吗?非常感谢任何帮助!

这里有一些使用指南。

filterset_classBaseInFilter

结合使用

views.py:

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets

from my_app.filters import MyFilter
from my_app.models import MyModel
from my_app.serializers import MySerializer


class MyViewSet(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MySerializer
    filter_backends = [DjangoFilterBackend]
    filterset_class = MyFilter
    lookup_field = 'id'

filters.py:

from django_filters.rest_framework import BaseInFilter, FilterSet, NumberFilter

from my_app.models import MyModel


class _NumberInFilter(BaseInFilter, NumberFilter):
    pass


class MyFilter(FilterSet):
    id__in = _NumberInFilter(field_name='id', lookup_expr='in')

    class Meta:
        model = MyModel
        fields = '__all__'

HTTP 请求(数量):

$ curl http://127.0.0.1:8000/my_app/my_view_set/?id__in=2,5,6
[{"id":5,"name":"Some name 5"},{"id":2,"name":"Some name 2"},{"id":6,"name":"Some name 6"}]
  • 请注意,查询参数中的查找是 id__in 而不仅仅是 id
  • 这里使用了
  • curl。为了方便访问,也可以在浏览器、Postman等输入

HTTP 请求(数字和字母):

$ curl http://127.0.0.1:8000/my_app/my_view_set/?id__in=2,5FD,6
{"id__in":["Enter a number."]}

使用filterset_fields

views.py:

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets

from my_app.models import MyModel
from my_app.serializers import MySerializer


class MyViewSet(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MySerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = {'id': ['in']}
    lookup_field = 'id'

HTTP 请求:

  • filterset_class
  • 相同

UI渲染错误

上面执行的 HTTP 请求是手动的,没有使用 djangorestframework 提供的 UI。在使用 UI 尝试时,我遇到了与您所述相同的问题:

But this solution doesn't allow me to input commas in the textbox anymore.

这与 django_filters 提供的过滤机制(发生在后端)无关,因为这是一个纯粹的前端问题,特别是表单验证。

我所做的手动解决方法是检查文本框(右键单击 + 检查),然后将 HTML 行从 number 更新为 text。所以来自:

<input type="number" name="id__in" step="any" id="id_id__in">

收件人:

<input type="text" name="id__in" step="any" id="id_id__in">

HTTP 请求(数量):

HTTP 请求(数字和字母):

您可能希望截取 djangorestframeworkdjango_filters 对 HTML 的实际呈现,以干净利落地执行此操作。