一、rest framework的分页
1、使用rest framework内置类PageNumberPagination实现分类
from django.conf.urls import url from api import views urlpatterns = [ url(r'^(?P<version>[v1|v2]+)/pager1/$', views.Pager1View.as_view()), ]
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.pagination import PageNumberPagination from api import models from api.utils.serializers.pager import PagerSerializer class Pager1View(APIView): """分页""" def get(self, request, *args, **kwargs): roles = models.Role.objects.all() # 使用PageNumberPagination类进行分页 pg = PageNumberPagination() # 获取分页数据 pager_roles = pg.paginate_queryset(queryset=roles, request=request, view=self) # 序列化分页结果 serl = PagerSerializer(instance=pager_roles, many=True) return Response(serl.data)
2、继承内置类自定义分页
from rest_framework.views import APIView from rest_framework.pagination import PageNumberPagination from api import models from api.utils.serializers.pager import PagerSerializer class MyPageNumberPagination(PageNumberPagination): """自定义分页类""" page_size = 2 # 设置一页显示2条数据 # page_size_query_param = None # 设置请求参数的key # 设置为size 可以在请求参数重置每页显示的数据条数 page_size_query_param = "size" # http://127.0.0.1:8082/api/v1/pager1/?size=3 max_page_size = 5 # 设置每页最大显示的数据条数 page_query_param = 'page' # 获取页码 http://127.0.0.1:8082/api/v1/pager1/?page=2 获取第二页数据 class Pager1View(APIView): """分页显示""" def get(self, request, *args, **kwargs): roles = models.Role.objects.all() pg = MyPageNumberPagination() # 获取分页数据 pager_roles = pg.paginate_queryset(queryset=roles, request=request, view=self) # 序列化分页结果 serl = PagerSerializer(instance=pager_roles, many=True) # return Response(serl.data) # 还可以使用内置方法返回数据 res = pg.get_paginated_response(serl.data) return res
3、LimitOffsetPagination类
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination from api import models from api.utils.serializers.pager import PagerSerializer class Pager1View(APIView): """分页显示""" def get(self, request, *args, **kwargs): roles = models.Role.objects.all() pg = LimitOffsetPagination() # 使用的是offset设置索引的ID # http://127.0.0.1:8082/api/v1/pager1/?offset=2 表示从第3条数据开始显示 # http://127.0.0.1:8082/api/v1/pager1/?offset=2&limit=4 表示从第3条数据开始向后取4条 # 获取分页数据 pager_roles = pg.paginate_queryset(queryset=roles, request=request, view=self) # 序列化分页结果 serl = PagerSerializer(instance=pager_roles, many=True) return Response(serl.data)
4、CursorPagination类
from rest_framework.views import APIView from rest_framework.pagination import CursorPagination from api import models from api.utils.serializers.pager import PagerSerializer class MyCursorPagination(CursorPagination): """自定义分页类""" cursor_query_param = 'cursor' page_size = 2 ordering = 'id' # 获取数据时的排序规则 page_size_query_param = None max_page_size = None class Pager1View(APIView): """分页显示""" def get(self, request, *args, **kwargs): roles = models.Role.objects.all() pg = MyCursorPagination() # 获取分页数据 pager_roles = pg.paginate_queryset(queryset=roles, request=request, view=self) # 序列化分页结果 serl = PagerSerializer(instance=pager_roles, many=True) res = pg.get_paginated_response(serl.data) return res
二、rest framework的视图
1、APIView
from django.conf.urls import url from api import views urlpatterns = [ url(r'^(?P<version>[v1|2]+)/viewer/$', views.ViewerView.as_view()), ]
from rest_framework.views import APIView from rest_framework.response import Response class ViewerView(APIView): """继承APIView""" def get(self, request, *args, **kwargs): return Response("xxx")
2、GenericAPIView
from django.db import models class UserGroup(models.Model): title = models.CharField(max_length=32) class UserInfo(models.Model): user_type_choices = ( (1, "普通用户"), (2, "vip"), (3, "svip"), ) user_type = models.IntegerField(choices=user_type_choices) username = models.CharField(max_length=32, unique=True) password = models.CharField(max_length=64) group = models.ForeignKey(to="UserGroup", on_delete=models.CASCADE, null=True, blank=True) roles = models.ManyToManyField(to="Role", blank=True) class UserToken(models.Model): user = models.OneToOneField(to="UserInfo") token = models.CharField(max_length=64) class Role(models.Model): title = models.CharField(max_length=32) class Order(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) create_time = models.DateTimeField(auto_now_add=True) user = models.ForeignKey(to="UserInfo", on_delete=models.CASCADE, null=True, blank=True)
from django.conf.urls import url from api import views urlpatterns = [ url(r'^(?P<version>[v1|2]+)/viewer/$', views.ViewerView.as_view()), ]
from rest_framework import serializers from api import models class ViewSerializer(serializers.ModelSerializer): class Meta: model = models.Role fields = "__all__"
from rest_framework.generics import GenericAPIView from rest_framework.response import Response from rest_framework.pagination import PageNumberPagination from api import models from api.utils.serializers.view_serializer import ViewSerializer class ViewerView(GenericAPIView): """继承GenericAPIView""" queryset = models.Role.objects.all() # 指定要查询的数据 serializer_class = ViewSerializer # 序列化类 pagination_class = PageNumberPagination # 分页类 def get(self, request, *args, **kwargs): roles = self.get_queryset() # 获取数据 pager = self.paginate_queryset(roles) # 分页 serl = self.get_serializer(instance=pager, many=True) # 序列化 return Response(serl.data)
3、GenericViewSet
继承了ViewSetMixin和GenericAPIView
from django.conf.urls import url from api import views urlpatterns = [ url(r'^(?P<version>[v1|2]+)/viewer/$', views.ViewerView.as_view({'get': 'list'})), ]
from rest_framework.viewsets import GenericViewSet from rest_framework.response import Response from rest_framework.pagination import PageNumberPagination from api import models from api.utils.serializers.view_serializer import ViewSerializer class ViewerView(GenericViewSet): """继承GenericViewSet""" queryset = models.Role.objects.all() # 指定要查询的数据 serializer_class = ViewSerializer # 序列化类 pagination_class = PageNumberPagination # 分页类 def list(self, request, *args, **kwargs): roles = self.get_queryset() # 获取数据 pager = self.paginate_queryset(roles) # 分页 serl = self.get_serializer(instance=pager, many=True) # 序列化 return Response(serl.data)
4、ListModelMixin、CreateModelMixin、GenericViewSet
ListModelMixin内部实现了list方法:
CreateModelMixin内部实现了create方法:
from django.conf.urls import url from api import views urlpatterns = [ url(r'^(?P<version>[v1|2]+)/viewer/$', views.ViewerView.as_view({'get': 'list', 'post': 'create'})), ]
from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import ListModelMixin, CreateModelMixin from rest_framework.pagination import PageNumberPagination from api import models from api.utils.serializers.view_serializer import ViewSerializer class ViewerView(ListModelMixin, CreateModelMixin, GenericViewSet): """继承ListModelMixin、CreateModelMixin、GenericViewSet""" queryset = models.Role.objects.all() # 指定要查询的数据 serializer_class = ViewSerializer # 序列化类 pagination_class = PageNumberPagination # 分页类
5、ModelViewSet
获取单条数据、更新数据、删除数据时,URL中需要传递要操作的数据的ID
from django.conf.urls import url from api import views urlpatterns = [ url(r'^(?P<version>[v1|2]+)/viewer/(?P<pk>d+)$', views.ViewerView.as_view({'get': 'retrieve', 'post': 'create', 'delete': 'destroy', 'put': 'update', 'patch': 'partial_update'})), ]
from rest_framework.viewsets import ModelViewSet from rest_framework.pagination import PageNumberPagination from api import models from api.utils.serializers.view_serializer import ViewSerializer class ViewerView(ModelViewSet): """继承ModelViewSet""" queryset = models.Role.objects.all() # 指定要查询的数据 serializer_class = ViewSerializer # 序列化类 pagination_class = PageNumberPagination # 分页类
6、当使用GenericViewSet类时,会执行它父类GenericAPIView里面的get_object方法,这个方法执行了check_object_permissions方法来对对象的权限进行校验:
三、rest framework的路由
url(r'^(?P<version>[v1|2]+)/viewer/$', views.ViewerView.as_view()) # http://127.0.0.1:8080/api/v2/viewer/ url(r'^(?P<version>[v1|2]+)/viewer/$', views.ViewerView.as_view({'get': 'list', 'post': 'create'})) # http://127.0.0.1:8080/api/v2/viewer/ # http://127.0.0.1:8080/api/v2/viewer/?format=json get传参的方式 url(r'^(?P<version>[v1|2]+)/viewer.(?P<format>w+)$', views.ViewerView.as_view({'get': 'list', 'post': 'create'})) # http://127.0.0.1:8080/api/v2/viewer.json 将参数写到路径里面
自动生成路由:
from django.conf.urls import url, include from rest_framework import routers from api import views router = routers.DefaultRouter() router.register(r"role", views.ViewerView) # url前缀,视图名称 router.register(r"group", views.ViewerView) urlpatterns = [ url(r'^(?P<version>[v1|2]+)/', include(router.urls)), ]
自动生成的路由:
可以通过http://127.0.0.1:8080/api/v2/role/ http://127.0.0.1:8080/api/v2/role.json等方式进行访问
四、rest framework的渲染器
1、局部配置
urlpatterns = [ url(r'^(?P<version>[v1|2]+)/test/$', views.TestView.as_view()), ]
from rest_framework import serializers from api import models class ViewSerializer(serializers.ModelSerializer): class Meta: model = models.Role fields = "__all__"
from rest_framework.views import APIView from rest_framework.viewsets import ModelViewSet from rest_framework.response import Response from rest_framework.pagination import PageNumberPagination from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer, AdminRenderer from api import models from api.utils.serializers.view_serializer import ViewSerializer class TestView(APIView): renderer_classes = [JSONRenderer, BrowsableAPIRenderer] # 渲染数据格式的类 http://127.0.0.1:8080/api/v2/test/?format=json # renderer_classes = [AdminRenderer, BrowsableAPIRenderer] # 渲染数据格式的类 http://127.0.0.1:8080/api/v2/test/?format=admin def get(self, request, *args, **kwargs): roles = models.Role.objects.all() pg = PageNumberPagination() pager_roles = pg.paginate_queryset(queryset=roles, request=request, view=self) serl = ViewSerializer(instance=pager_roles, many=True) return Response(serl.data)
2、全局配置
在项目的settings里面: