分页(my)
第一种 PageNumberPagination 看第n页,每页显示n条数据
http://127.0.0.1:8000/book_page?page=2&size=1
1,创建App:startapp Pagenation
2,settings.py注册app: 'Pagenation'
3,urls.py:
from Pagenation.views import BookPageView urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^book_page',BookPageView.as_view()), ]
4,views.py:
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from SerDemo.models import Book from SerDemo.serializers import BookSerializer from rest_framework import pagination # ========自定义分页类======= class MyPagenation(pagination.PageNumberPagination): page_size= 2 #每页显示两条数据 page_query_param = 'page' #url上的路径page=??? page_size_query_param = 'size' #每页放多少条数据 max_page_size = 3 #每页最多显示三天数据 # ===============视图======== class BookPageView(APIView): def get(self,request): queryset = Book.objects.all() #取路由地址的数据 my_pagenation = MyPagenation() #分页器实例化的对象 # 根据request传过来的数据让他在视图里显示每页多少个数据做处理 page_queryset = my_pagenation.paginate_queryset(queryset,request,view=self) ser_obj = BookSerializer(page_queryset,many=True) #序列化 return Response(ser_obj.data) def post(self,request): ser_obj = BookSerializer(data=request.data) #post提交的序列化的数据 if ser_obj.is_valid(): #做校验 ser_obj.save() return Response(ser_obj.validated_data) #校验的数据 else: return Response(ser_obj.errors) # Create your views here.
5,SerDemo.serializers
#序列化器 from rest_framework import serializers from .models import Book class PublisherSerializer(serializers.Serializer): id = serializers.IntegerField() title = serializers.CharField(max_length=32) class AuthorSerializer(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField(max_length=32) # book_obj = { # "title": "xxx", # "category": 1, # "publisher": 1, # "authors": [1, 2] # } # (read_only, write_only)针对正序反序字段不统一 # 正序走read_only=True #自定义校验必须放在类最外边,如果对字段进行校验 #三个权重分别是自定义>单个字段的验证>全局的联合验证 def my_validate(value): #对敏感字符进行过滤 if "马化腾" in value.lower(): raise serializers.ValidationError("不能含有敏感字符") else: return value # class BookSerializer(serializers.Serializer): # id = serializers.IntegerField(required=False) #required=False反序列化的时候不进行校验(因为字段不统一) # title = serializers.CharField(max_length=32,validators=[my_validate]) # # validators = [my_validate] 自定义检验 # CHOICES = ((1, "python"), (2, "linux"), (3, "go")) # category = serializers.CharField(max_length=32,source="get_category_display",read_only=True)#read_only=True展示的时候不显示 # #get_category_display去中文也可以连表 # # # post_category = serializers.ChoiceField(choices=CHOICES,write_only=True) # # pub_time = serializers.DateField() # # # publisher = PublisherSerializer(read_only=True) #创建关联的序列化 # author = AuthorSerializer(many=True,read_only=True) # many=True序列化多个 # # publisher_id = serializers.IntegerField(write_only=True) # author_list = serializers.ListField(write_only=True) # # # def create(self, validated_data): # # 执行ORM的新增数据的操作 # book_obj = Book.objects.create(title=validated_data["title"], category=validated_data["post_category"], # pub_time=validated_data["pub_time"], publisher_id=validated_data["publisher_id"]) # book_obj.author.add(*validated_data["author_list"]) # print(validated_data["author_list"]) # return book_obj # # def update(self, instance, validated_data): # # 有就更新没有就取默认的 # instance.title = validated_data.get("title", instance.title) # instance.category = validated_data.get("post_category", instance.category) # instance.put_time = validated_data.get("put_time", instance.pub_time) # instance.publisher_id = validated_data.get("publisher_id", instance.publisher_id) # if validated_data.get("author_list"): # instance.authors.set(*validated_data["author_list"]) # instance.save() #反序列化的保存 # return instance # # # # # # #验证,单个字段的验证:validate_title # # def validate_title(self, value): #验证的钩子 # # if "go" not in value.lower(): # raise serializers.ValidationError("内容必须含有go") # else: # return value # # # #联合校验:validate # # def validate(self, attrs): #attrs有我们所有的字段和数据是个字典 # #要求title必须含有go,并且分类是1 # if "go" in attrs["title"].lower() and attrs["post_category"] == 1: # return attrs # else: # raise serializers.ValidationError('数据不合法,请重新输入') # # raise 断言抛出异常错误 ValidationError #有些属性需要显示,有些属性不需要显示 class BookSerializer(serializers.ModelSerializer): category_dis = serializers.SerializerMethodField(read_only=True)#depth获取不到自己写 publisher_info = serializers.SerializerMethodField(read_only=True) author_info = serializers.SerializerMethodField(read_only=True) def get_author_info(self,obj): authors = obj.author.all() #通过obj拿到author ret = [] #构建想要的数据结构返回 for author in authors: ret.append({ "id":author.id, "name":author.name }) return ret def get_category_dis(self,obj): return obj.get_category_display() #自定义方法显示什么 def get_publisher_info(self,obj): #obj序列化的Book对象 #通过Book对象找到我们的publisher对象 #就可以拿到我们想要的字段,拼接成自己想要的数据结构 ret = { "id":obj.publisher.id, "title":obj.publisher.title } return ret class Meta: model = Book #指定的魔性是book #fields = ["id","title","pub_time"] #指定默认展示哪些字段 fields = "__all__" #取所有字段 # depth = 1 #能取到外键的字段,category没有取到,需要自己写覆盖里边的category字段 #depth = 1,数字是虚招外键关系的层数,depth = 2,寻找外键关系第二层, # 这个方法让你这些外键关系的字段变成read_only=True,,这是个坑!! extra_kwargs = {"category":{"write_only":True},"publisher":{"write_only":True}, "authors": {"write_only": True}} #给默写字段指定参数:正序不显示
6,SerDemo.models
from django.db import models # Create your models here. __all__ = ["Book","Publisher","Author"] class Book(models.Model): title = models.CharField(max_length=32, verbose_name="图书的名字") #verbose_name 在admin里显示的名字 CHOICES = ((1,"Python"),(2,"Linux"),(3,"Go")) category = models.IntegerField(choices=CHOICES) #category分类 pub_time = models.DateField() publisher = models.ForeignKey(to="Publisher") author = models.ManyToManyField(to="Author") def __str__(self): #admin表里字段显示中文 return self.title class Meta: db_table = "01-图书表" #在admin里清晰的显示表名 verbose_name_plural = db_table class Publisher(models.Model): title = models.CharField(max_length=32,verbose_name="出版的名称") def __str__(self): return self.title class Meta: db_table="02-出版社表" verbose_name_plural = db_table class Author(models.Model): name = models.CharField(max_length=32,verbose_name="作者的名字") def __str__(self): return self.name class Meta: db_table="03-作者表" verbose_name_plural = db_table
数据可迁移
浏览器起服务: http://127.0.0.1:8000/book_page?page=2&size=2
第二种 LimitOffsetPagination 在第n个位置 向后查看n条数据
http://127.0.0.1:8000/book_page?offset=2&limit=1
分页器类,
pagenator.py:
from rest_framework import pagination # ========自定义分页类======= #第一种 PageNumberPagination 看第n页,每页显示n条数据 # class MyPagination(pagination.PageNumberPagination): # page_size= 2 #每页显示两条数据 # page_query_param = 'page' #url上的路径page=??? # page_size_query_param = 'size' #每页放多少条数据 # max_page_size = 3 #每页最多显示三天数据 # 第二种 LimitOffsetPagination 在第n个位置 向后查看n条数据 class LimitPagination(pagination.LimitOffsetPagination): default_limit=1 #每页的数量 limit_query_param = 'limit' offset_query_param = 'offset' max_limit = 2
views.py:
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from SerDemo.models import Book from SerDemo.serializers import BookSerializer from rest_framework import pagination from .pagenator import MyPagination,LimitPagination # ===============视图======== class BookPageView(APIView): def get(self,request): queryset = Book.objects.all().order_by("id") #取路由地址的数据 # my_pagenation = MyPagination() #分页器实例化的对象 #实例化分页器 my_pagination = LimitPagination() # 根据request传过来的数据让他在视图里显示每页多少个数据做处理 page_queryset = my_pagination.paginate_queryset(queryset,request,view=self) ser_obj = BookSerializer(page_queryset,many=True) #序列化 # return Response(ser_obj.data) return my_pagination.get_paginated_response(ser_obj.data)
第三种 CursorPagination 加密游标的分页 把上一页和下一页的id记住
http://127.0.0.1:8000/book_page
pagenator.py:
from rest_framework import pagination # ========自定义分页类======= # 第一种 PageNumberPagination 看第n页,每页显示n条数据 # class MyPagination(pagination.PageNumberPagination): # page_size= 2 #每页显示两条数据 # page_query_param = 'page' #url上的路径page=??? # page_size_query_param = 'size' #每页放多少条数据 # max_page_size = 3 #每页最多显示三天数据 # 第二种 LimitOffsetPagination 在第n个位置 向后查看n条数据 # class LimitPagination(pagination.LimitOffsetPagination): # default_limit=1 #每页的数量 # limit_query_param = 'limit' # offset_query_param = 'offset' # max_limit = 2 # 第三种 CursorPagination 加密游标的分页把上一页和下一页的id记住 class MyCursorPagination(pagination.CursorPagination): page_size = 1 #每页显示的数据 cursor_query_param = 'cursor' ordering = 'id' #排序,倒序
views.py:
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from SerDemo.models import Book from SerDemo.serializers import BookSerializer from rest_framework import pagination from .pagenator import MyPagination,LimitPagination,MyCursorPagination # ===============视图======== class BookPageView(APIView): def get(self,request): queryset = Book.objects.all().order_by("id") #取路由地址的数据 # 分页器实例化的对象 # my_pagenation = MyPagination() 第一种 # my_pagination = LimitPagination() 第二种 my_pagination = MyCursorPagination() #第三种 # 根据request传过来的数据让他在视图里显示每页多少个数据做处理 page_queryset = my_pagination.paginate_queryset(queryset,request,view=self) ser_obj = BookSerializer(page_queryset,many=True) #序列化 # return Response(ser_obj.data) return my_pagination.get_paginated_response(ser_obj.data)
表见上边代码
posted on 2018-11-01 19:47 liangliang123456 阅读(104) 评论(0) 编辑 收藏 举报