私はDjango残りのフレームワークAPIを使用しています。first_nameまたはlast_nameまたはその両方でフィルターを作成しようとしています。これが私のContactViewSet.pyです。 :
class ContactViewSet(viewsets.ModelViewSet):
queryset = Contact.objects.all()
serializer_class = ContactSerializer
filter_backends = (DjangoFilterBackend, )
filter_fields = ('first_name', 'last_name')
lookup_field = 'idContact'
DRFの設定:
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('Django_filters.rest_framework.DjangoFilterBackend',),
}
私のactuelリクエストURLは次のようになります:
http://localhost:8000/api/v1/contacts/?first_name=Clair&last_name=Test
しかし、私はこのようなものを探しています:
http://localhost:8000/api/v1/contacts/?first_name=Cl**&last_name=Tes**
任意の助けをいただければ幸いです。
クラスContactFilterを次のように変更して問題を解決しました。
import Django_filters
from .models import Contact
class ContactFilter(Django_filters.FilterSet):
class Meta:
model = Contact
fields = {
'first_name': ['startswith'],
'last_name': ['startswith'],
}
together = ['first_name', 'last_name']
そして私の見解では、私はこれをしなければなりませんでした:
class ContactViewSet(viewsets.ModelViewSet):
queryset = Contact.objects.all()
serializer_class = ContactSerializer
filter_class = ContactFilter
私のリクエストURLは次のようになります:
http://localhost:8000/api/v1/contact/?first_name__contains=Cl&last_name__contains=Tes
しかし、私はまだDjangoでこのようなものができるかどうか疑問に思っています
http://localhost:8000/api/v1/contacts/?first_name=Cl**&last_name=Tes**
私がすることは、カスタムFilterBackendを書くことです。このようなもの:
# views.py
from rest_framework import filters
class ObjektFilterBackend(filters.BaseFilterBackend):
allowed_fields = ['objekt', 'naziv', 'kategorija', 'zadnja_sprememba']
def filter_queryset(self, request, queryset, view):
flt = {}
for param in request.query_params:
for fld in self.allowed_fields:
if param.startswith(fld):
flt[param] = request.query_params[param]
return queryset.filter(**flt)
class ObjektiViewSet(mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
authentication_classes = (
authentication.TokenAuthentication,
authentication.SessionAuthentication)
permission_classes = (IsAuthenticated,)
queryset = models.Objekt.objects.all()
serializer_class = serializers.ObjektSerializer
filter_backends = (ObjektFilterBackend, ObjektOrderBackend,)
....
基本的なフィルタリング(fieldname = valueのペア)の他に、次のようなURLで任意の Django queryset Field Lookups (__gt、__gte、__startswith、...)を使用できます。
http://localhost:8000/api/v2/objekti/?naziv__startswith=Apartma&zadnja_sprememba__gte=2018-01-01
また、ObjektFilterBackendクラスは、パターンによる検索をサポートするように簡単に調整できます。
ほんの少しの警告-この方法はエンドユーザーが外部キーフィールドでもフィルタリングできるため、潜在的に危険です。このようなものも機能します:
http://localhost:8000/api/v2/objekti/?kategorija__naziv__icontains=sobe
したがって、allowed_fieldsを慎重に制限し、関連するユーザーモデルにつながる可能性のある外部キーを含めないでください。
DjangoFilterBackendは、主に等価ベースのフィルタリングだと思います。ただし、 フィルタリング方法をカスタマイズする はできます。
また、DRFでは、厳密でないフィルタリングのために、デフォルトで大文字と小文字を区別しない部分一致検索を行う SearchFilter があります。
あいまい検索ルックアップでは、このアプローチを使用することをお勧めします。
filters.py
from Django_filters import rest_framework as filters
from Django.db.models import Q
from . import models
def filter_name(queryset, name, value):
"""
Split the filter value into separate search terms and construct a set of queries from this. The set of queries
includes an icontains lookup for the lookup fields for each of the search terms. The set of queries is then joined
with the OR operator.
"""
lookups = [name + '__icontains', ]
or_queries = []
search_terms = value.split()
for search_term in search_terms:
or_queries += [Q(**{lookup: search_term}) for lookup in lookups]
return queryset.filter(reduce(operator.or_, or_queries))
class ContactFilter(filters.FilterSet):
first_name = filters.CharFilter(method=filter_name, name='first_name')
last_name = filters.CharFilter(method=filter_name, name='last_name')
class Meta:
model = models.Contact
fields = [
'first_name',
'last_name',
]
api.py
class ContactViewSet(viewsets.ModelViewSet):
queryset = Contact.objects.all()
serializer_class = ContactSerializer
filter_class = ContactFilter
...
リクエストがそれほど複雑でない場合は、次の方法も使用できます。
class YourModelViewSet(viewsets.ModelViewSet):
queryset = YourModel.objects.all()
serializer_class = YourModelSerializer
filter_fields = {'some_field': ['startswith']}
リクエストクエリパラメータで '?some_field__starswith = text'構文のサポートを有効にするものはどれですか。
「startswith」は、Django standart queryset filter param。