路漫漫其修远兮
吾将上下而求索

drf学习:分页、视图、路由、渲染器

P48day131-01 今日内容概要

P49day131-02 内容回顾

P50day131-03 rest framework之序列化源码流程和bug修复

P51day131-04 rest framework之分页

P52day131-05 rest framework之分页内容梳理

P53day131-06 rest framework之视图

P54day131-07 rest framework之视图内容梳理

P55day131-08 rest framework之路由

P56day131-09 rest framework之渲染器

P57day131-10 今日作业

P48day131-01 今日内容概要
1、分页
2、视图
3、路由




P49day131-02 内容回顾
P50day131-03 rest framework之序列化源码流程和bug修复
P51day131-04 rest framework之分页

分页:
    a、分页,看第n页,每页显示n条数据
    b、分页、在n个位置,向后查看n条数据
    c、加密的分页、只能看上一页和下一页,


1、简单的分页功能,
需要在settings文件里面设置参数:'PAGE_SIZE': 3,表示默认每页显示3条数据
这里使用roles表进行测试,往里面写20条数据
请求方式:http://127.0.0.1:8000/api/pages/?page=4
from rest_framework.pagination import PageNumberPagination
class PagesSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'


class PagesView(APIView):
    def get(self, request, *args, **kwargs):
        roles = models.Role.objects.all()

        #创建分页对象
        pg = PageNumberPagination()
        #在数据库获取分页数据
        pager_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
        #print(pager_roles)
        
        #对分页数据序列化
        ser = PagesSerializer(instance=pager_roles, many=True)
        ret = json.dumps(ser.data)
        return HttpResponse(ret)


2、根据自带的类,重写一个类,里面定制一些变量
请求方式:http://127.0.0.1:8000/api/pages/?p=4&size=3
显示第几页,每页显示多少

from rest_framework.pagination import PageNumberPagination
class MyPageNumberPagination(PageNumberPagination):
    #每页显示多少
    page_size = 2
    #表示可以定制每页显示多少个
    page_size_query_param = 'size'
    #每页最大显示5个
    max_page_size = 5

    #显示页面名称
    page_query_param = 'p'


class PagesSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'


class PagesView(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)
        #print(pager_roles)

        #对分页数据序列化
        ser = PagesSerializer(instance=pager_roles, many=True)
        ret = json.dumps(ser.data)
        return HttpResponse(ret)


3、根据自带的类,重写一个类,里面定制一些变量
请求方式:http://127.0.0.1:8000/api/pages/?offset=3&limit=5
从哪个位置开始显示,向后显示多少个

from rest_framework.pagination import LimitOffsetPagination
class MyPageNumberPagination(LimitOffsetPagination):
    default_limit = 2
    limit_query_param = 'limit'
    offset_query_param = 'offset'

    max_limit = 5


class PagesSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'


class PagesView(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)
        #print(pager_roles)

        #对分页数据序列化
        ser = PagesSerializer(instance=pager_roles, many=True)
        ret = json.dumps(ser.data)
        return HttpResponse(ret)


4、加密分页
from rest_framework.pagination import CursorPagination




P52day131-05 rest framework之分页内容梳理
如果数据量大的话,如何做分页
    



P53day131-06 rest framework之视图

还可以继承GenericAPIView,里面实现了很多方法,但是不常用,没有省多少事情

from rest_framework.generics import GenericAPIView

class GeneView(GenericAPIView):
    queryset = models.Role.objects.all()
    serializer_class = PagesSerializer
    pagination_class = PageNumberPagination

    def get(self,request,*args,**kwargs):
        #获取数据 models.Role.objects.all()
        roles = self.get_queryset()
        #分页
        pager_roles = self.paginate_queryset(roles)
        #序列化
        ser = self.get_serializer(instance=pager_roles, many=True)
        return HttpResponse(ser.data)


        

还可以继承GenericViewSet,对应的父类为两个:class GenericViewSet(ViewSetMixin, generics.GenericAPIView)

必须指定get方法对应某个类的方法,而不是默认的get,post
ViewSetMixin里面还有一个as_view,重写了as_view方法,重写了get方法

url(r'genera/$', GeneView.as_view({'get':'list'})),

from rest_framework.viewsets import GenericViewSet
class GeneView(GenericViewSet):
    def list(self, request, *args, **kwargs):
        return HttpResponse('hello')

        
        

还可以继承ModelViewSet,其父类有多个
class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,  获取单条数据
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
                   
继承的ListModelMixin类里面已经帮我们写好了list等方法,不用我们自己写list方法,更简单
继承的CreateModelMixin类里面已经帮我们写好了create等方法,不用我们自己写create方法,更简单

url文件
url(r'genera/$', GeneView.as_view({'get':'list','post':'create'})),

view文件
from rest_framework.viewsets import ModelViewSet

class GeneView(ModelViewSet):
    queryset = models.Role.objects.all()
    serializer_class = PagesSerializer
    pagination_class = PageNumberPagination


    
    
当路径中最后传入id的时候,表示要对单条数据进行更新删除操作
比如请求:http://127.0.0.1:8000/api/genera/2/ ,表示对该数据进行操作

对应这种情况,当以数字结尾的url,单独进行处理,   对应的父类里面都已经把对应的方法写好了,
这里只用指定get方法执行对应RetrieveModelMixin类里面的retrieve方法即可,
获取所有数据和单条数据对应的方法不同,如果自己做的话,需要单独判断进行处理
这里只用指定put方法执行对应UpdateModelMixin类里面的update方法即可
url(r'genera/$', GeneView.as_view({'get':'list','post':'create'})),
url(r'genera/(?P<pk>\d+)/$', GeneView.as_view({'get':'retrieve',
                                               'delete':'destroy',
                                               'put':'update',
                                               'patch':'partial_update'})),     
        
views文件
from rest_framework.viewsets import GenericViewSet,ModelViewSet

class GeneView(ModelViewSet):
    queryset = models.Role.objects.all()
    serializer_class = PagesSerializer
    pagination_class = PageNumberPagination

    


P54day131-07 rest framework之视图内容梳理

自己写视图类的时候,如果有增删改查都有使用modelviewset更简单
如果是只有增删功能,使用createmodels,destroymodels
如果是复杂的视图类,可以使用apiviewset,更原始,更灵活

关于权限,还有一种权限has_object_permission,在GenericAPIView类的get_object方法里面,表示检查用户是否有访问该对象的权限




P55day131-08 rest framework之路由

当在浏览器里面把路径写错的时候,所有的路径都会显示出来
会自动生成四个对应的url,两组
url.py内容 
from django.conf.urls import url,include
from rest_framework import routers
from app01.views import GeneView

router = routers.DefaultRouter()
router.register(r'xxx', GeneView)
router.register(r'rrr', GeneView)

urlpatterns = [
    url(r'aaa/', include(router.urls))
]


views.py内容
class GeneView(ModelViewSet):
    queryset = models.Role.objects.all()
    serializer_class = PagesSerializer
    pagination_class = PageNumberPagination
    



浏览器输入
http://127.0.0.1:8000/api/aaa/xxxx/

^api/ aaa ^xxx/$ [name='role-list']
^api/ aaa ^xxx\.(?P<format>[a-z0-9]+)/?$ [name='role-list']

下面是单个数据对应的
^api/ aaa ^xxx/(?P<pk>[^/.]+)/$ [name='role-detail']
^api/ aaa ^xxx/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='role-detail']




P56day131-09 rest framework之渲染器

下面的示例表示允许两种访问方式,json方式和浏览器方式,当设置为JSONRenderer,表示只允许json方式访问

from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class GeneView(ModelViewSet):
    renderer_classes = [BrowsableAPIRenderer,JSONRenderer]
    queryset = models.Role.objects.all()
    serializer_class = PagesSerializer
    pagination_class = PageNumberPagination


浏览器的模板也可以修改为自己喜欢的方式,也可以放到配置文件中,全局生效
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer

class MyBrowsableAPIRenderer(BrowsableAPIRenderer):
    media_type = 'text/html'
    format = 'api'
    template = 'rest_framework/api.html'
    filter_template = 'xxx/base.html'


class GeneView(ModelViewSet):
    renderer_classes = [MyBrowsableAPIRenderer,JSONRenderer]
    queryset = models.Role.objects.all()
    serializer_class = PagesSerializer
    pagination_class = PageNumberPagination




P57day131-10 今日作业

未经允许不得转载:江哥架构师笔记 » drf学习:分页、视图、路由、渲染器

分享到:更多 ()

评论 抢沙发

评论前必须登录!