Nae*_*lla 7 python django django-rest-framework django-rest-swagger
我正在使用Django rest framework 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'
Run Code Online (Sandbox Code Playgroud)
我的DRF设置:
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
}
Run Code Online (Sandbox Code Playgroud)
我的actuel请求网址如下所示:
http://localhost:8000/api/v1/contacts/?first_name=Clair&last_name=Test
Run Code Online (Sandbox Code Playgroud)
但是我正在寻找这样的东西:
http://localhost:8000/api/v1/contacts/?first_name=Cl**&last_name=Tes**
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激 ..
我通过像这样修改我的类 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']
Run Code Online (Sandbox Code Playgroud)
在我看来,我只需要这样做:
class ContactViewSet(viewsets.ModelViewSet):
queryset = Contact.objects.all()
serializer_class = ContactSerializer
filter_class = ContactFilter
Run Code Online (Sandbox Code Playgroud)
我的请求 URL 如下所示:
http://localhost:8000/api/v1/contact/?first_name__contains=Cl&last_name__contains=Tes
Run Code Online (Sandbox Code Playgroud)
但我仍然想知道我是否可以在 Django 中拥有这样的东西:
http://localhost:8000/api/v1/contacts/?first_name=Cl**&last_name=Tes**
Run Code Online (Sandbox Code Playgroud)
我认为 DjangoFilterBackend 主要是基于相等的过滤。但是您可以自定义过滤方法。
同样在 DRF 中,对于非精确过滤,还有SearchFilter,它默认进行不区分大小写的部分匹配搜索。
我所做的是编写自定义 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,)
....
Run Code Online (Sandbox Code Playgroud)
除了基本过滤(字段名=值对),我可以在我的 URL 中使用任何Django 查询集字段查找(__gt、__gte、__startswith...),如下所示:
http://localhost:8000/api/v2/objekti/?naziv__startswith=Apartma&zadnja_sprememba__gte=2018-01-01
Run Code Online (Sandbox Code Playgroud)
并且 ObjektFilterBackend 类可以很容易地适应以支持按模式搜索。
只是一点警告 - 这种方法有潜在危险,因为它允许最终用户也通过外键字段进行过滤。像这样的东西也有效:
http://localhost:8000/api/v2/objekti/?kategorija__naziv__icontains=sobe
Run Code Online (Sandbox Code Playgroud)
因此,请仔细限制 allowed_fields,不要包含可能导致相关 User 模型的外键。
| 归档时间: |
|
| 查看次数: |
8576 次 |
| 最近记录: |