分页器
目录
一、图书的创建
1、models
from django.db import models
# Create your models here.
from django.contrib.auth.models import AbstractUser
class BaseModel(models.Model):
# is_delete = models.BooleanField(choices=((0, '未删除'), (1, '删除')), default=0)
is_delete = models.BooleanField(default=False)
create_time = models.DateTimeField(auto_now_add=True)
last_update_time = models.DateTimeField(auto_now=True)
class Meta:
# 可以修改表名,可以建联合索引
'''
单个字段可以建唯一键索引
多个字段:联合索引,联合唯一
'''
abstract = True # 抽象表,不在数据库建立表
class Book(BaseModel):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8, decimal_places=2)
# db_constraint=False:逻辑上关联上了,实际上没有外键关联,增删不会受到外键影响,orm查询也不影响
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE, db_constraint=False)
author = models.ManyToManyField(to='Author', db_constraint=False)
class Meta:
verbose_name_plural = '图书表'
def __str__(self):
return self.name
@property # 把方法包装成数据属性
def publish_detail(self):
return {'name': self.publish.name, 'addr': self.publish.addr}
@property # 把方法包装成数据属性
def author_detail(self):
# 获取所有作者
author_list = self.author.all()
author_list_dict = []
for author in author_list:
author_list_dict.append({'name': author.name, 'sex': author.get_sex_display()})
return author_list_dict
class Publish(BaseModel):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
class Meta:
verbose_name_plural = '出版社表'
def __str__(self):
return self.name
class Author(BaseModel):
name = models.CharField(max_length=32)
sex = models.IntegerField(choices=((1, '男'), (2, '女')))
authordetail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE, db_constraint=False)
class Meta:
verbose_name_plural = '作者表'
def __str__(self):
return self.name
class AuthorDetail(BaseModel):
mobile = models.CharField(max_length=22, verbose_name='手机号')
class Meta:
verbose_name_plural = '作者详细表'
def __str__(self):
return self.mobile
# 二、表断关联
# 1、表之间没有外键关联,但是有外键逻辑关联(有充当外键的字段)
# 2、断关联后不会影响数据库查询效率,但是会极大提高数据库增删改效率(不影响增删改查操作)
# 3、断关联一定要通过逻辑保证表之间数据的安全
# 4、断关联
# 5、级联关系
# 作者没了,详情也没:on_delete=models.CASCADE
# 出版社没了,书还是那个出版社出版:on_delete=models.DO_NOTHING
# 部门没了,员工没有部门(空不能):null=True, on_delete=models.SET_NULL
# 部门没了,员工进入默认部门(默认值):default=0, on_delete=models.SET_DEFAULT
2、admin.py
from django.contrib import admin
from api import models
admin.site.register(models.Book)
admin.site.register(models.Publish)
admin.site.register(models.Author)
admin.site.register(models.AuthorDetail)
2.1、创建超级用户
createsuperuser
3、serializer.py
from rest_framework import serializers
from api.models import Book
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['id', 'title', 'price', 'publish', 'author', 'publish_detail', 'author_detail']
extra_kwargs = {
'publish': {'write_only': True},
'author': {'write_only': True},
'publish_detail': {'read_only': True},
'author_detail': {'read_only': True}
}
4、views.py(批量增、改、删)
from django.shortcuts import render
from rest_framework.views import APIView
from api.models import Book
from api.serializer import BookModelSerializer
from rest_framework.response import Response
class BookView(APIView):
def get(self, request, *args, **kwargs):
# 查询单条和查询所有,合在一起
book_list = Book.objects.all().filter(is_delete=False)
ser = BookModelSerializer(instance=book_list, many=True)
return Response(data=ser.data)
def post(self, request, *args, **kwargs):
# 增加单条数据
if isinstance(request.data, dict): # isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
ser = BookModelSerializer(data=request.data)
ser.is_valid(raise_exception=True)
ser.save()
return Response(data=ser.data)
elif isinstance(request.data, list):
# 增加多条数据
ser = BookModelSerializer(data=request.data, many=True) # 加上many增加多条
ser.is_valid(raise_exception=True)
ser.save() # 调用的是ListSerializer方法
return Response(data=ser.data)
# 批量删除和删除单个数据
def delete(self, request, *args, **kwargs):
# 删除单条数据
pk = kwargs.get('pk')
pks = []
if pk:
pks.append(pk)
else:
pks = request.data.get('pks')
# ret:受影响的行数
ret = Book.objects.filter(pk__in=pks, is_delete=False).update(is_delete=True)
if ret:
return Response(data={'msg': '删除成功'})
else:
return Response(data={'msg': '没有要删除的数据'})
5、路由分发urls
# 项目
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
# 路由分发
path('api/', include('api.urls')),
]
# app
from django.urls import path
from api import views
urlpatterns = [
path('books/', views.BookView.as_view()),
path('books/<int:pk>', views.BookView.as_view()),
]
二、分页器Pagination
1、基本使用
REST framework提供了分页的支持。
我们可以在配置文件中设置全局的分页方式,如:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 2 # 每页数目
}
1.1、views.py
# 只有查所有才需要分页
from rest_framework.generics import ListAPIView
# 内置三种分页方式
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
class Book2View(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = PageNumberPagination
# 请求方式:http://127.0.0.1:8000/api/books2/page=3
2.1、通过自定义类分页
也可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过
pagination_clas属性来指明。
# 只有查所有才需要分页
from rest_framework.generics import ListAPIView
# 内置三种分页方式
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
# 自定义类
class MyPageNumberPagination(PageNumberPagination):
page_size = 3 # 每页条数
page_size_query_param = 'page_size' # 每一页显示的条数
max_page_size = 100 # 每页最大显示条数
page_query_param = 'aaa' # 查询第几页key
class Book2View(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = MyPageNumberPagination # 自定义类
# 请求方式:http://127.0.0.1:8000/api/books2/?aaa=2&page_size=3
三、可选分页器
1、PageNumberPagination
前端访问网址形式:
GET http://127.0.0.1:8000/api/books2/?aaa=2&page_size=3
可以在子类中定义的属性:
- page_size 每页数目
- page_query_param 前端发送的页数关键字名,默认为”page”
- page_size_query_param 前端发送的每页数目关键字名,默认为None
- max_page_size 前端最多能设置的每页数量
# 只有查所有才需要分页
from rest_framework.generics import ListAPIView
# 内置三种分页方式
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
一、添加配置文件分页
class Book2View(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = PageNumberPagination # 自定义类
二、自定义类分页
# 自定义类
class MyPageNumberPagination(PageNumberPagination):
page_size = 3 # 每页条数
page_size_query_param = 'page_size' # 每一页显示的条数
max_page_size = 100 # 每页最大显示条数
page_query_param = 'aaa' # 查询第几页key
class Book2View(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = MyPageNumberPagination # 自定义类
# 请求方式:http://127.0.0.1:8000/api/books2/?aaa=2&page_size=3
2、LimitOffsetPagination
前端访问网址形式:
GET http://127.0.0.1:8000/api/books2/?limit=3&offset=1
可以在子类中定义的属性:
- default_limit 默认限制,默认值与
PAGE_SIZE设置一直 - limit_query_param limit参数名,默认’limit’
- offset_query_param offset参数名,默认’offset’
- max_limit 最大limit限制,默认None
# 只有查所有才需要分页
from rest_framework.generics import ListAPIView
# 内置三种分页方式
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
一、添加配置文件分页
class Book2View(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = LimitOffsetPagination # 自定义类
二、自定义类分页
# 自定义类
class MyCursorPagination(CursorPagination):
default_limit = 3 # 每页条数
limit_query_param = 'limit' # 向后展示几条
offset_query_param = 'offset' # 标杆
max_limit = None # 每页最大展示几条
class Book2View(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = MyCursorPagination # 自定义类
3、CursorPagination
前端访问网址形式:
GET http://127.0.0.1/api/books2/?cursor=cD0xNQ%3D%3D
可以在子类中定义的属性:
- cursor_query_param:默认查询字段,不需要修改
- page_size:每页数目
- ordering:按什么排序,需要指
# 只有查所有才需要分页
from rest_framework.generics import ListAPIView
# 内置三种分页方式
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
# 自定义类
class MyCursorPagination(CursorPagination):
cursor_query_param = 'cursor' # 每一页查询的key
page_size = 2 # 显示每页的条数
ordering = '-created' # 排序字段
class Book2View(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = MyCursorPagination
3.1、使用APIView实现分页器
# 只有查所有才需要分页
from rest_framework.generics import ListAPIView
# 内置三种分页方式
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
# 自定义类
class MyPageNumberPagination(PageNumberPagination):
page_size = 3
page_size_query_param = 'page_size'
# max_page_size = 10000
page_query_param = 'aaa'
# 使用APIView分页
class Book2View(APIView):
def get(self, request, *args, **kwargs):
# 获取所有数据
book_list = Book.objects.all()
# 创建分页对象
page = MyPageNumberPagination()
# 在数据库中获取分页的数据
book_list = page.paginate_queryset(book_list, request, view=self)
# 下一页和上一页
next_url = page.get_next_link()
pr_url = page.get_previous_link()
# 对分页进行序列化
ser = BookModelSerializer(book_list, many=True)
return Response(data=ser.data)

浙公网安备 33010602011771号