分页

基础分页  

自定义分页类完成配置:paginations.py

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

 

 搜索过滤器

views.py

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两个字段

排序

views.py

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 按价格降序,价格相同时按主键升序

 分类与区间

安装django-filter插件:pip install django-filter

自定义过滤规则类:filters.py

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']

views.py

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的所有课程

自定义

自定义过滤类:filters.py

# 自定义过滤器:自定义普通类,实现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  # 没过滤

views.py

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']
View Code
#  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
View Code
#  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  # 没过滤
View Code

posted on 2020-01-13 22:19  啥是py  阅读(174)  评论(0编辑  收藏  举报

导航