分页(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()),

]
View Code

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.
View Code

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}}
        #给默写字段指定参数:正序不显示
View Code

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
View Code

数据可迁移

浏览器起服务:  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)
View Code

第三种 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编辑  收藏  举报

导航