Django:drf过滤、搜索、排序功能
过滤功能实现
1.get_query_set方法过滤
编辑blogs目录下的views.py,新增get_queryset方法
class ArticleListViewset(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet): serializer_class = ArticleSerializer pagination_class = StandardResultsSetPagination def get_queryset(self): queryset = Article.objects.all() click_num = self.request.query_params.get('click', 0) if click_num: queryset = queryset.filter(click_num__gte=30) return queryset
在浏览器输入 http://localhost:8000/api/v1/articles/?click=50
,click代表参数值过滤了大于50点击数的文章。但是当过滤参数多的时候此过滤方法写起来比较麻烦
2.django-filters方法过滤
pip install django-filter 安装django-filter
在settings.py注册配置django-filters,在REST_FRAMEWORK 加上过滤器会对全局生效,如果只针对特定视图可以单独在view里面加
①settings.py全局过滤器
编辑settings.py
# 注册添加过滤模块 INSTALLED_APPS = [ ..., 'django_filters', ..., ] # 添加过滤器,全局生效 REST_FRAMEWORK = { ..., 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',) }
②视图添加DjangoFilterBackend过滤器
新增 filter_backends
和 filterset_fields
from django_filters.rest_framework import DjangoFilterBackend class ArticleListViewset(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer pagination_class = StandardResultsSetPagination filter_backends = [DjangoFilterBackend] filterset_fields = ['category', 'user']
运行后在界面上出现了 过滤器
,增加了 文章类别
和 文章作者
两个过滤字段,可以选择并且联合过滤。但是有缺点就是无法按照区间进行过滤,比如点击量
③使用filterset方法自定义过滤
在blogs目录下新建filters.py文件,用来写过滤
from django_filters import rest_framework as filters from .models import Article class ArticleFilter(filters.FilterSet): """ 文章的过滤类 """ click_min = filters.NumberFilter(field_name="click_num", lookup_expr='gte') click_max = filters.NumberFilter(field_name="click_num", lookup_expr='lte') favor_min = filters.NumberFilter(field_name='favor_num', help_text="最低收藏量", lookup_expr='gte') comment_min = filters.NumberFilter(field_name='comment_num', help_text="最低评论量", lookup_expr='gte') title = filters.CharFilter(field_name='title', help_text='按标题模糊查询', lookup_expr='icontains') class Meta: model = Article fields = ['category', 'tags', 'user', 'title', 'click_min', 'click_max', 'favor_min', 'comment_min']
编辑blogs目录下的views.py,去掉filterset_fields,新增 filterset_class
from blogs.filters import ArticleFilter class ArticleListViewset(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer pagination_class = StandardResultsSetPagination filterset_class = ArticleFilter
运行打开过滤器后可以看到过滤条件都有了
搜索功能实现
使用SearchFilter方法,filter_backends新增SearchFilter,新增search_fields
from rest_framework.filters import SearchFilter class ArticleListViewset(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer pagination_class = StandardResultsSetPagination filter_backends = [DjangoFilterBackend, SearchFilter] filterset_class = ArticleFilter search_fields = ['title', 'brief', 'content']
搜索框输入 父亲
,请求路径变成了 http://localhost:8000/api/v1/articles/?search=父亲
排序功能实现
使用OrderingFilter方法,filter_backends新增OrderingFilter,新增ordering_fields
from rest_framework.filters import SearchFilter, OrderingFilter class ArticleListViewset(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet): """文章列表页,分页,搜索,过滤,排序""" queryset = Article.objects.all() serializer_class = ArticleSerializer pagination_class = StandardResultsSetPagination filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_class = ArticleFilter search_fields = ['title', 'brief', 'content'] ordering_fields = ['click_num', 'favor_num', 'comment_num', 'add_time']
运行后过滤器可以看到过滤器字段、搜索、排序功能
转:http://www.zhangyanc.club/article/fiter-search/
DRF过滤器文档:http://www.iamnancy.top/djangorestframework/Filtering/
django-filters官方文档:https://django-filter.readthedocs.io/en/master/guide/rest_framework.html