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_class
与 BaseInFilter
结合使用
- https://django-filter.readthedocs.io/en/stable/guide/rest_framework.html#adding-a-filterset-with-filterset-class
- https://django-filter.readthedocs.io/en/stable/ref/filters.html#baseinfilter
- 注意参数
queryset
和serializer_class
是view类的字段,不是过滤器类.
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
- https://django-filter.readthedocs.io/en/stable/guide/rest_framework.html#using-the-filterset-fields-shortcut
- https://django-filter.readthedocs.io/en/stable/guide/usage.html#generating-filters-with-meta-fields
- https://django-filter.readthedocs.io/en/stable/ref/filterset.html#declaring-filterable-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 请求(数字和字母):
您可能希望截取 djangorestframework
或 django_filters
对 HTML 的实际呈现,以干净利落地执行此操作。
我目前正在尝试使用 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_class
与 BaseInFilter
结合使用
- https://django-filter.readthedocs.io/en/stable/guide/rest_framework.html#adding-a-filterset-with-filterset-class
- https://django-filter.readthedocs.io/en/stable/ref/filters.html#baseinfilter
- 注意参数
queryset
和serializer_class
是view类的字段,不是过滤器类.
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
- https://django-filter.readthedocs.io/en/stable/guide/rest_framework.html#using-the-filterset-fields-shortcut
- https://django-filter.readthedocs.io/en/stable/guide/usage.html#generating-filters-with-meta-fields
- https://django-filter.readthedocs.io/en/stable/ref/filterset.html#declaring-filterable-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 请求(数字和字母):
您可能希望截取 djangorestframework
或 django_filters
对 HTML 的实际呈现,以干净利落地执行此操作。