36 - 分页 & 过滤

一. 分页

REST framework提供了分页的支持

1. 全局配置 内置分页

          (1). settings.py 配置
REST_FRAMEWORK ={
        "DEFAULT_PAGINATION_CLASS":"rest_framework.pagination.PageNumberPagination"
        "PAGE_SIZE":2  # 每页数目
}
        (2). 定义序列化器  
from rest_framework import serializers
from app01.models import User

# 人物序列化
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"

        (3). 定义视图函数
# 继承ListAPIView
class UserListView(ListAPIView):
    # 查询结果集
    queryset = User.objects.all()
    # 序列化器
    serializer_class = UserSerializer
        (4). 定义路由
 path('userlist/', views.UserListView.as_view(), name="userlist"),

2. 自定义 分页类

        (1). 自定义分页类
from collections import OrderedDict

from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response


class UserListPager(PageNumberPagination):
    page_size = 2  # 每页2条记录
    page_size_query_param = 'page_size'  # 每页记录数的参数名字

    # 自定义分页形式
    def get_paginated_response(self, data):
        return Response(OrderedDict([
            ('count', self.page.paginator.count), # 总条数
            ('page_range', list(self.page.paginator.page_range)),  # 页码范围
            ('has_next', self.page.has_next()),  # 是否有下一页
            ('has_previous', self.page.has_previous()),  # 是否有上一页
            # ('next_page_number', self.page.next_page_number()),  # 返回下一页页码 ,没有的话会报错
            # ('previous_page_number', self.page.previous_page_number()),  # 返回上一页页码 ,没有的话会报错
            ('result', data)  # 当前页内容
        ]))
        (2). 定义序列化器
from rest_framework import serializers
from app01.models import User

# 人物序列化
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"

        (3). 定义视图类
class UserListView(ListAPIView):
    # 查询结果集
    queryset = User.objects.all()
    # 序列化器
    serializer_class = UserSerializer

    # 分页类
    pagination_class = UserListPager

    def get(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset()) # 查询结果集

        page = self.paginate_queryset(queryset) # # 当前页 内容对象
        if page is not None:
            serializer = self.get_serializer(page, many=True) # 序列化
            return self.get_paginated_response(serializer.data) # 分页样式

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
        (4). 定义路由
    path('userlist/', views.UserListView.as_view(), name="userlist"),

二. 过滤

过滤: 对于列表数据可能需要根据字段进行过滤,请求时携带定义的字段,返回对应的数据
 

1. 安装第三方库

pip install django-filter==2.2.0
 
# django-filters支持的pytho和django版本:
# Python: 3.5,3.6,3.7, 3.8
# Django: 1.11, 2.0, 2.1, 2.2, 3.0
# DRF:3.10+

  2. settings.py配置

INSTALLED_APPS =[
    ...
    "django_filters", # 需要注册应用
]
 
REST_FRAMEWORK ={
  "DEFAULT_FILTER_BACKENDS": ('django_filters.rest_framework.DjangoFilterBackend',)
}

3. 定义序列化器

from rest_framework import serializers
from app01.models import User

# 人物序列化
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        # fields = "__all__"
        fields = ["uid","email","username","password"]

4. 定义视图类 使用过滤

      两种方式:

        (1). 视图中直接指定字段过滤
# 视图调用
class UserListView(ListAPIView):
    # 查询结果集
    queryset = User.objects.all()
    # 序列化器
    serializer_class = UserSerializer
    
    # 1. 视图中直接指定过滤字段
    # http://127.0.0.1:8000/userlist/?uid=4&email=123@qq.com
    filter_fields = ("uid", "email")
        (2). 自定义 过滤类, 视图中调用 
# 自定义过滤类 MyFilter.py
from django_filters import rest_framework as filters

from app01.models import User


class UserFilter(filters.FilterSet):
    # 1. 在类中定义字段
    # 查询字段名不要求和模型中一模一样
    # field_name: 模型中的字段名;  method:查询方法(底部定义的自定义方法)
    # http://127.0.0.1:8000/list/?comment=3
    username = filters.CharFilter(field_name='username', method='find_username')

    class Meta:
        model = User
        # 2. 在fileds中定义字段
        fields = {
            # 模型字段名  进行那些运算(运算符和ORM中运算符一模一样)
            # http://127.0.0.1:8000/list/?username__icontains=春
            'email': ['icontains', 'startswith', 'endswith'],  # 不区分大小写的包含

            # http://127.0.0.1:8000/list/?uid__gt=1&bread__lt=3
            'uid': ['exact', 'lt', 'gt', 'lte', 'in'],  # 精确判断,
        }

    # 自定义过滤条件
    def find_username(self, queryset, name, value):
        """
        :param queryset:
        :param name: 查询字段名
        :param value: 查询的值
        :return: queryset
        """
        print(queryset)
        print(name, value)
        return queryset.filter(username__icontains=value) # 包含
# 视图中调用
class UserListView(ListAPIView):
    # 查询结果集
    queryset = User.objects.all()
    # 序列化器
    serializer_class = UserSerializer

    # 过滤器
    # filter_fields = ["uid","username"]
    # 指定过滤类
    filter_class = UserFilter

 

5. 定义路由

 path('userlist/', views.UserListView.as_view(), name="userlist"),

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值