分页器组件使用方式介绍
-
分页器组件使用方式介绍
-
导入模块
from rest_framework.pagination import PageNumberPagination
-
获取数据
books = BookInfo.objects.all()
-
创建一个分页器对象
paginater = PageNumbberPageination()
-
开始分页
paged_books = paginater.paginate_queryset(books, request)
-
开始序列化
serialized_books = BookSerializer(paged_books, many=True)
-
返回数据
return Response(serializer_books.data)
-
-
分页器组件局部实现
-
导入模块
from rest_framework.pagination import PageNumberPagination
-
自定义一个分页类并继承PageNumberPagination
class MyPagination(PageNumberPagination): pass
-
实例化一个分页类对象
paginater = MyPagination()
-
-
分页器组件全局实现
-
就是在setting理配置分页器, 把视图里指定分页器类注释掉就行, 其他跟案例相同
REST_FRAMEWORK = { "PAGE_SIZE": 4, "PAGE_QUERY_PARAM": "page", "PAGE_SIZE_QUERY_PARAM": "size", "MAX_PAGE_SIZE": 5 }
-
-
分页器组件几个参数介绍
- page_size: 用来控制每页显示多少条数据(全局参数名为PAGE_SIZE)
- page_query_param: 用来提供直接访问某页的数据
- page_size_query_param: 临时调整当前显示多少条数据
- max_page_size: 控制page_size_query_param参数能调整的最大条数
案列, 视图用ModelViewSet举得例子, 也可以用APIView
- models.py
from django.db import models from datetime import datetime # from django.contrib.auth.models import AbstractUser class UserInfo(models.Model): username = models.CharField(max_length=32, verbose_name="用户名") password = models.CharField(max_length=40, verbose_name="用户密码") user_type_entry = ( (1, "Delux"), (2, "SVIP"), (3, "VVIP") ) user_type = models.IntegerField(choices=user_type_entry) class Meta: db_table = "db_user_info" verbose_name = "用户信息" verbose_name_plural = verbose_name def get_user_type_display(self): return self.user_type_entry[self.user_type] class UserToken(models.Model): # OneToOneField一对一关系 # on_delete=models.CASCADE 当UserInfo数据表里面的数据被删除后UserToken里面的数据也随着被删除 user = models.OneToOneField("UserInfo", on_delete=models.CASCADE, verbose_name="一对一关系") token = models.CharField(max_length=128, verbose_name="token") class Meta: db_table = "db_user_token" verbose_name = "用户token" verbose_name_plural = verbose_name class AuthorInfo(models.Model): name = models.CharField(max_length=32, verbose_name="作者名称") age = models.IntegerField(verbose_name="作者年龄") class Meta: db_table = "db_author_info" verbose_name = "作者信息" verbose_name_plural = verbose_name def __str__(self): return self.name class PublishInfo(models.Model): name = models.CharField(max_length=32, verbose_name="出版社名称") city = models.CharField(max_length=32, verbose_name="出版社所在城市") email = models.EmailField(verbose_name="出版社邮箱") class Meta: db_table = "db_publish_info" verbose_name = "出版社信息" verbose_name_plural = verbose_name def __str__(self): return self.name class BookInfo(models.Model): title = models.CharField(max_length=32, verbose_name="书名") publishDate = models.DateField(default=datetime.now, verbose_name="出版日期") # max_digits小数位加整数位多少长度 decimal_places小数位长度为2 price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="图书价格") publish = models.ForeignKey(PublishInfo, related_name="book", related_query_name="book_query", on_delete=models.CASCADE, verbose_name="出版社") # ManyToManyField多对多 authors = models.ManyToManyField(AuthorInfo, verbose_name="图书作者") class Meta: db_table = "db_book_info" verbose_name = "图书信息" verbose_name_plural = verbose_name def __str__(self): return self.title
- url.py
from django.urls import re_path, include from .views import BookView from rest_framework import routers router = routers.DefaultRouter() router.register(r"books", BookView) urlpatterns = [ re_path("^", include(router.urls)) ]
- 定义一个分页类并继承PageNumberPagination
from rest_framework.pagination import PageNumberPagination class MyPagination(PageNumberPagination): # 每页显示的数据 page_size = 2 # 你这里赋值的是page, 你get请求传递的键必须是page 获取第几页的数据 page_query_param = "page" # 你这里赋值的是size, 你get请求传递的键必须是size 每页多少条数据 page_size_query_param = "size" # 每页最大5条 max_page_size = 5
- 序列化类
from.models import BookInfo # 第一步: 导入模块 from rest_framework import serializers from datetime import datetime class BookSerializer(serializers.ModelSerializer): class Meta: # 指定 要操作的模型类 model = BookInfo # 指定序列化的字段 fields = ( "title", "price", "publishDate", "publish", "authors", "author_list", "publish_name", "publish_city" ) # 指定那些字段是只写的 # write_only只写的 (只写的 前端发送数据时要写它, 后端返回数据时没有它) extra_kwargs = { "publish": {"write_only": True}, "authors": {"write_only": True} } # 自定义的字段 # read_only只读的 (只读的 前端发送数据时不用写它, 后端返回数据时有它) publish_name = serializers.CharField(max_length=32, read_only=True, source="publish.name") publish_city = serializers.CharField(max_length=32, read_only=True, source="publish.city") author_list = serializers.SerializerMethodField() def get_author_list(self, book_obj): # 拿到queryset开始循环 [ {}, {}, {}] authors = [] for author in book_obj.authors.all(): authors.append(author.name) return authors
- views.py
from rest_framework.viewsets import ModelViewSet from .utils.app_paginaters import MyPagination from .models import BookInfo from .app_serializers import BookSerializer class BookView(ModelViewSet): # 指定分页类 pagination_class = MyPagination queryset = BookInfo.objects.all() serializer_class = BookSerializer
- postman效果图
源码剖析
用APIView的案列
- 其他都一样就视图改变了
from rest_framework.views import APIView from rest_framework.response import Response from .utils.app_paginaters import MyPagination from .models import BookInfo from .app_serializers import BookSerializer class BookView(APIView): def get(self, request): # 获取数据 books = BookInfo.objects.all() # 创建一个分页器对象 paginater = MyPagination() # 开始分页 paged_books = paginater.paginate_queryset(books, request) # 开始序列化 serialized_books = BookSerializer(paged_books, many=True) # 返回数据 return Response(serialized_books.data)