filter.py
import django_filters
from .models import Book
class BookFileter(django_filters.FilterSet):
title = django_filters.CharFilter(lookup_expr='icontains') # title字段按照模糊查询
publish = django_filters.CharFilter(lookup_expr='icontains') # publish字段按照模糊查询
class Meta:
model = Book
fields = ['title', 'publish']
view.py
from django_filters.rest_framework import DjangoFilterBackend
from .filters import BookFileter
class BookView(ViewSetMixin, ListAPIView, CreateModelMixin):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 配置过滤类
filter_backends = [DjangoFilterBackend, ]
# 按照我们写的过滤类过滤
filterset_class = BookFileter
========================================================================
方式二
from rest_framework.filters import BaseFilterBackend
from django_filters import FilterSet
from django.db.models import Q
class AsBaseFilterBackend(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
name = request.query_params.get('name',None)
publish = request.query_params.get('publish', None)
if name and publish:
queryset = queryset.filter(Q(name__icontains=name,publish__icontains=publish))
return queryset
elif name:
queryset = queryset.filter(name__icontains=name)
return queryset
elif publish:
queryset = queryset.filter(publish__icontains=publish)
return queryset
else:
return queryset
方式三
class BooksView(APIView):
def get(self,request):
book_query = Book.objects.all()
page_obj = PagePaginate(request.query_params,book_query)
queryset=page_obj.filter_queryset()
ser = BookSerializer(instance=MyFilter().filter_query(request,queryset), many=True)
return Response(page_obj.show_result(ser))
class PagePaginate:
pass # 上个博客
class MyFilter:
def filter_query(self,request,queryset):
title=request.query_params.get('title',None)
author=request.query_params.get('author',None)
if title:
queryset=queryset.filter(title__icontains=title)
if author:
queryset=queryset.filter(author__icontains=author)
return queryset
方式四
# 自定义一个过滤类,实现可以通过图书名或作者模糊匹配
from rest_framework.filters import BaseFilterBackend
from django.db.models import Q
class RewriteFilter(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
# 在这里实现过滤,要返回qs对象,过滤后的数据
print(request.query_params)
name = request.query_params.get('name', None)
author = request.query_params.get('author', None)
# 只要名字中有传过来的name或作者中有传过来的author即可
qs = queryset.filter(Q(name__icontains=name) | Q(author__icontains=author))
return qs
# 编写一个全局异常处理,让它生效
from rest_framework.response import Response
from rest_framework.views import exception_handler
def common_exception_handler(exc, context):
# 内置的异常处理函数,只处理了drf的异常(继承了APIException的异常)
response = exception_handler(exc, context)
# 如果response有值,说明错误被处理了:Http404(404的)、PermissionDenied(没有权限)、APIException(没有登录)
if response:
# 返回drf的错误原因,如果取不到detail,返回未知错误
return Response({'code': 800, 'msg': 'drf错误,错误原因是:%s' % response.data.get('detail', '未知错误')})
# 如果是None,说明错误没有被处理,这个错误不是drf的错误,而是django或代码的错误,返回错误对象
return Response({'code': 900, 'msg': '系统错误,错误原因是:%s' % str(exc)})
--------有能力的写------
使用django-filter实现模糊匹配
1.视图类
class BookView(ModelViewSet):
filter_backends = [DjangoFilterBackend]
filterset_class = QueryFilter
serializer_class = BookSerializer
queryset = Book.objects.all()
2.过滤类
import django_filters
class QueryFilter(django_filters.FilterSet):
# 指定name字段的过滤条件为icontains
name = django_filters.CharFilter(lookup_expr='icontains')
# 指定author字段的过滤条件为icontains
author = django_filters.CharFilter(lookup_expr='icontains')
class Meta:
model = Book
fields = {'name', 'author'}
方式五
class NewFilter(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
name = request.query_params.get('name', None)
publish = request.query_params.get('publish', None)
if name and publish:
qs = queryset.filter(Q(name__icontains=name) | Q(publish__icontains=publish))
return qs
elif name:
qs = queryset.filter(name__icontains=name)
return qs
else:
qs = queryset.filter(publish__icontains=publish)
return qs
# 使用django-filter实现模糊匹配
# 方式一:
class BookFilter(django_filters.rest_framework.FilterSet):
name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
class Meta:
model = Book
fields = ['name']
# 方式二:
class BookFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = Book
fields = {"name": "icontains"}