分页
基础分页
from rest_framework import pagination # 基础分页 class PageNumberPagination(pagination.PageNumberPagination): # 默认一页显示的条数 page_size = 2 # 查询第page页面的关键字 page_query_param = 'page' # 用户自定义一页显示条数的关键字 page_size_query_param = 'page_size' # 用户最大可自定义一页显示的条数 max_page_size = 2 # 偏移分页,从第offset页开始,显示limit条数据 class LimitOffsetPagination(pagination.LimitOffsetPagination): # 默认一页显示的条数 default_limit = 2 # 用户自定义一页显示的条数 limit_query_param = 'limit' # 用户自定义偏移的条数 offset_query_param = 'offset' # 用户最大可自定义一页显示的条数 max_limit = 2
注:接口分页前后,response的格式不一样
分页前:数据是response.data
分页后:数据是response.data.results
搜索过滤器
from rest_framework.filters import SearchFilter class FreeCourseListViewSet(ListModelMixin, GenericViewSet): queryset = models.Course.objects.filter(is_delete=False, is_show=True).all() serializer_class = serializers.CourseModelSerializer # 配置搜索组件 filter_backends = [SearchFilter] # 配置参与搜索字段 search_fields = ['name', 'brief'] # 规则: # 参与全文搜索的字段为name和brief(两个字段必须都是数据库表字段) # 接口:?search=搜索关键字,会全文匹配name和brief两个字段
排序
from rest_framework.filters import OrderingFilter class FreeCourseListViewSet(ListModelMixin, GenericViewSet): queryset = models.Course.objects.filter(is_delete=False, is_show=True).all() serializer_class = serializers.CourseModelSerializer # 配置排序组件 filter_backends = [OrderingFilter] # 配置参与排序字段 ordering_fields = ['price', 'id', 'students'] # 规则: # ?ordering=price 按价格升序 # ?ordering=-price 按价格降序 # ?ordering=id 按主键升序 # ?ordering=-price,id 按价格降序,价格相同时按主键升序
分类与区间
from django_filters import filters from . import models class CourseFilterSet(FilterSet): # 实现区间:field_name关联model表属性,lookup_expr设置过滤规则 min_price = filters.NumberFilter(field_name='price', lookup_expr='gte') max_price = filters.NumberFilter(field_name='price', lookup_expr='lte') class Meta: model = models.Course # min_price 和 max_price 自定义规则字段可以不在fields中配置 fields = ['course_category']
from django_filters.rest_framework import DjangoFilterBackend from .filters import CourseFilterSet class FreeCourseListViewSet(ListModelMixin, GenericViewSet): queryset = models.Course.objects.filter(is_delete=False, is_show=True).all() serializer_class = serializers.CourseModelSerializer # 配置过滤组件 filter_backends = [DjangoFilterBackend] # 配置过滤规则的类 filter_class = CourseFilterSet # 规则: # ?course_category=1 课程分组1所有的课程 # ?min_price=10 课程价格大于等于10的所有课程 # ?min_price=10&max_price=100 课程价格大于等于10小于等于100的所有课程
自定义
# 自定义过滤器:自定义普通类,实现filter_queryset可以接受request, queryset, view返回过滤处理后的queryset即可 class MyFilter: def filter_queryset(self, request, queryset, view): # 过滤条件是死的,?count=数字,也可以写高级一点,从view中去反射配置信息,或者将配置信息放在settings中 count = request.query_params.get('count', None) if not count: return queryset # 没过滤 try: count = int(count) return queryset[:count] # 过滤 except: return queryset # 没过滤
from .filters import MyFilter class FreeCourseListViewSet(ListModelMixin, GenericViewSet): queryset = models.Course.objects.filter(is_delete=False, is_show=True).all() serializer_class = serializers.CourseModelSerializer # 配置排序组件 filter_backends = [MyFilter]
# view.py from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import ListModelMixin, RetrieveModelMixin from . import models, serializers class CategoryListViewSet(ListModelMixin, GenericViewSet): queryset = models.CourseCategory.objects.filter(is_delete=False, is_show=True).all() serializer_class = serializers.CategoryModelSerializer # 过滤组件:分页、搜索、排序、分类、区间 # 自定义分页组件 from . import paginations # drf默认提供两个过滤组件:排序、搜索 from rest_framework.filters import SearchFilter, OrderingFilter # drf默认不能完成 分类、区间 两种过滤,需要借助第三方插件:pip install django-filter from django_filters.rest_framework import DjangoFilterBackend # 自定义规则类 from .filters import CourseFilterSet, MyFilter class FreeCourseViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): queryset = models.Course.objects.filter(is_delete=False, is_show=True).all() serializer_class = serializers.CourseModelSerializer # 走系统分页类 # pagination_class = pagination.PageNumberPagination # pagination.PageNumberPagination.page_size = 2 # 走自定义分页类 基础分页 pagination_class = paginations.PageNumberPagination # 偏移分页 # pagination_class = paginations.LimitOffsetPagination # 注:接口分页前后,response的格式不一样 # 分页前:数据是response.data # 分页后:数据是response.data.results # """ # 过滤类:有filter_queryset(self, request, queryset, view)方法,返回值是queryset filter_backends = [SearchFilter, OrderingFilter, DjangoFilterBackend] # SearchFilter组件: # 参与全文搜索的字段为name和brief(两个字段必须都是数据库表字段,不能是自定义字段) # 接口:?search=搜索关键字,会全文匹配name和brief两个字段 search_fields = ['name', 'brief'] # OrderingFilter组件: # 参与排序字段为price、id和students(三个字段必须都是数据库表字段) # 接口: # ?ordering=price 按价格升序 # ?ordering=-price 按价格降序 # ?ordering=id 按主键升序 # ?ordering=-price,id 按价格降序,价格相同时按主键升序 ordering_fields = ['price', 'id', 'students'] # django-filter插件的DjangoFilterBackend组件: # 第一种配置,配置字段: # filter_fields = ['course_category'] # 第二个配置,配置类 filter_class = CourseFilterSet # """ """自定义过滤器 filter_backends = [MyFilter] """ class SearchCourseListViewSet(ListModelMixin, GenericViewSet): queryset = models.Course.objects.filter(is_delete=False, is_show=True).all() serializer_class = serializers.CourseModelSerializer filter_backends = [SearchFilter] search_fields = ['name'] pagination_class = paginations.PageNumberPagination class CourseChapterViewSet(ListModelMixin, GenericViewSet): queryset = models.CourseChapter.objects.filter(is_delete=False, is_show=True).all() serializer_class = serializers.CourseChapterModelSerializer filter_backends = [DjangoFilterBackend] filter_fields = ['course']
# paginations.py from rest_framework import pagination # 基础分页 class PageNumberPagination(pagination.PageNumberPagination): # 默认一页显示的条数 page_size = 2 # 查询页面的关键字 page_query_param = 'page' # 用户自定义一页显示条数的关键字 page_size_query_param = 'page_size' # 用户最大可自定义一页显示的条数 max_page_size = 10 class LimitOffsetPagination(pagination.LimitOffsetPagination): # 默认一页显示的条数 default_limit = 2 # 用户自定义一页显示的条数 limit_query_param = 'limit' # 用户自定义偏移的条数 offset_query_param = 'offset' # 用户最大可自定义一页显示的条数 max_limit = 10
# filters.py from django_filters.filterset import FilterSet from django_filters import filters from . import models class CourseFilterSet(FilterSet): # 实现区间:field_name关联model表属性,lookup_expr设置过滤规则 min_price = filters.NumberFilter(field_name='price', lookup_expr='gte') max_price = filters.NumberFilter(field_name='price', lookup_expr='lte') class Meta: model = models.Course # min_price 和 max_price 自定义规则字段可以不在fields中配置 fields = ['course_category'] # 自定义过滤器:自定义普通类,实现filter_queryset可以接受request, queryset, view返回过滤处理后的queryset即可 class MyFilter: def filter_queryset(self, request, queryset, view): # 过滤条件是死的,?count=数字,也可以写高级一点,从view中去反射配置信息,或者将配置信息放在settings中 count = request.query_params.get('count', None) if not count: return queryset # 没过滤 try: count = int(count) return queryset[:count] # 过滤 except: return queryset # 没过滤