Я пришел из этой проблемы https://github.com/carltongibson/django-filter/issues/919, вот что случилось:
Я хочу сделать нечеткий поиск по списку с помощью django-фильтра (определенный поиск по списку и одиночный нечеткий поиск в порядке).
Во-первых, модель продукта:
from django.db import models
class Product(models.Model):
...
name = models.CharField(max_length=16)
type = models.CharField(max_length=16)
...
и два продукта, хранящиеся в базе данных:
{
"name": "tomato",
"type": "vegetable"
}
{
"name": "orange",
"type": "fruit"
}
и сериализатор:
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
name = serializers.CharField()
type = serializers.CharFIeld()
class Meta:
model = Product
fields = '__all__'
затем ListFilter :
import django_filters
from django_filters.fields import Lookup
from .models import Product
class ListFilter(django_filters.Filter):
def filter(self, qs, value):
value_list = value.split(u',')
return super(ListFilter, self).filter(qs, Lookup(value_list, 'in'))
затем просмотр (я поставил ListFilter
в utils.django_filters
):
from rest_framework import generics
from django_filters import rest_framework as filters
from utils.django_filters import ListFilter
from .models import Product
from .serializers import ProductSerializer
class ProductFilter(filters.FilterSet):
type = ListFilter(name='type')
class Meta:
model = Product
fields = {
'type': ['exact', 'contains'],
}
class ProductList(generics.ListCreateAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_class = ProductFilter
наконец URL:
from django.urls import path
from . import views
path('product-list', views.ProductList.as_view(), name='product-list')
Ниже приведены контрольные примеры и результаты:
GET /api/product/product-list?type=fruit
-> [orange]
GET /api/product/product-list?type=vegetable
-> [tomato]
GET /api/product/product-list?type=fruit,vegetable
-> [orange, tomato]
GET /api/product/product-list?type__contains=fru
-> [orange]
GET /api/product/product-list?type__contains=vege
-> [tomato]
GET /api/product/product-list?type__contains=fru,vege
-> []
GET /api/product/product-list?type__contains=fruit,vegetable
-> []
Я ожидаю, что последние два результата будут [orange, tomato]
, возможно ли это сделать?