Django Restful Framework【第五篇】分页、视图、路由、渲染器

一、分页

试问如果当数据量特别大的时候,你是怎么解决分页的?

  • 方式a、记录当前访问页数的数据id
  • 方式b、最多显示120页等
  • 方式c、只显示上一页,下一页,不让选择页码,对页码进行加密

1、基于limit offset 做分页

from rest_framework.pagination import LimitOffsetPagination

urls.py

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^app01/(?P<version>[v1|v2]+)/‘, include(‘app01.urls‘))

]

app01.url

urlpatterns = [
    url(r‘^index1/‘, views.IndexView1.as_view()),
    url(r‘^index2/‘, views.IndexView2.as_view()),
    url(r‘^index3/‘, views.IndexView3.as_view()),
    url(r‘^index4/‘, views.IndexView4.as_view()),
    url(r‘^index5/‘, views.IndexView5.as_view()),

]

views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from app01.serializes.myserializes import MySerializes
from rest_framework.pagination import LimitOffsetPagination
from app01 import models

# =========== 可以自己进行自定制分页,基于limitoffset===================
class P1(LimitOffsetPagination):
    max_limit = 3  # 最大限制默认是None
    default_limit =2  # 设置每一页显示多少条
    limit_query_param = ‘limit‘  # 往后取几条
    offset_query_param = ‘offset‘  # 当前所在的位置

class IndexView2(APIView):
    #使用http://127.0.0.1:8080/app01/v1/index2/?offset=2&limit=4可进行判断
    def get(self,request,*args,**kwargs):
        user_list = models.UserInfo.objects.all()
        p1 = P1()#注册分页
        page_user_list = p1.paginate_queryset(queryset=user_list,request=request,view=self)
        print(‘打印的是分页的数据‘,page_user_list)
        ser = MySerializes(instance=page_user_list,many=True)  #可允许多个
        # return Response(ser.data) #不含上一页下一页
        return p1.get_paginated_response(ser.data)

=======================也可以用下面这种形式===========
class BaseResponse(object):
    def __init__(self,code=1000,data=None,error=None):
        self.code = code
        self.data = data
        self.error = error
class IndexView(views.APIView):
    ‘‘‘第二种类表示的方式‘‘‘
    def get(self,request,*args,**kwargs):
        ret = BaseResponse()
        try:
            user_list = models.UserInfo.objects.all()
            p1 = P1()
            page_user_list = p1.paginate_queryset(queryset=user_list,request=request,view=self)
            ser = IndexSerializer(instance=page_user_list,many=True)
            ret.data = ser.data
            ret.next = p1.get_next_link()
        except Exception as e:
            ret.code= 1001
            ret.error = ‘xxxx错误‘
        return Response(ret.__dict__)

 

2、基于页码的分页

from rest_framework.pagination import PageNumberPagination
# ======================基于页码实现的分页==============
class P2(PageNumberPagination):
    #默认每页显示的数据条数
    page_size = 2
    #获取url参数中设置的每页显示数据条数
    page_size_query_param = ‘size‘
    #获取url中传入的页码key
    page_query_param = ‘page‘
    #最大支持的每页显示的数据条数
    max_page_size = 5

class IndexView3(APIView):
    #使用http://127.0.0.1:8080/app01/v1/index3/?page=1&page_size=1可进行判断
    def get(self,request,*args,**kwargs):
        user_list = models.UserInfo.objects.all()
        #实例化分页对象,获取数据库中的分页数据
        p2 = P2()
        print(p2.page_size_query_description)
        page_user_list = p2.paginate_queryset(queryset=user_list,request=request,view=self)
        print(‘打印的是分页的数据‘,page_user_list)

        #序列化对象
        ser = MySerializes(instance=page_user_list,many=True)  #可允许多个

        #生成分页和数据
        # return Response(ser.data) #不含上一页下一页
        return p2.get_paginated_response(ser.data)

3、基于Cursor的分页

2可能存在性能问题,如果用户吧page给改的很大,查询速度就会很慢。还有一种页码加密的方式,

# =====================基于Cursor的分页============
class P3(CursorPagination):
    # URL传入的游标参数
    cursor_query_param = ‘cursor‘
    # 默认每页显示的数据条数
    page_size = 2
    # URL传入的每页显示条数的参数
    page_size_query_param = ‘size‘
    # 每页显示数据最大条数
    max_page_size = 3

    # 根据ID从大到小排列
    ordering = "id"

class IndexView4(APIView):
    #使用http://127.0.0.1:8080/app01/v1/index4/?cursor=cj0xJnA9NA%3D%3D&size=3可进行判断
    def get(self,request,*args,**kwargs):
        user_list = models.UserInfo.objects.all().order_by(‘-id‘)
        p3 = P3()#注册分页
        page_user_list = p3.paginate_queryset(queryset=user_list,request=request,view=self)
        print(‘打印的是分页的数据‘,page_user_list)
        ser = MySerializes(instance=page_user_list,many=True)  #可允许多个
        # return Response(ser.data) #不含上一页下一页
        return p3.get_paginated_response(ser.data)

  

二、视图

写视图函数可继承的几个类,我们以前经常用到的是APIView,现在我们来了解一下其他的类,其中1、3、4用到的最多

需要导入的类

from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import GenericViewSet
from rest_framework.viewsets import ModelViewSet

1、APIView

class IndexView2(APIView):
    def get(self,request,*args,**kwargs):
        user_list = models.UserInfo.objects.all()
        ser = MySerializes(instance=user_list,many=True)
        return Response(ser.data)

2、GenericAPIView(APIView)

from rest_framework.response import Response
from rest_framework.generics import GenericAPIView
from app01 import models
from app01.serializes.myserializes import MySerializes
from rest_framework.pagination import LimitOffsetPagination
class P1(LimitOffsetPagination):
    max_limit = 3  # 最大限制默认是None
    default_limit =2  # 设置每一页显示多少条
    limit_query_param = ‘limit‘  # 往后取几条
    offset_query_param = ‘offset‘  # 当前所在的位置

class IndexView1(GenericAPIView):
    queryset = models.UserInfo.objects.all()
    serializer_class = MySerializes
    pagination_class = P1
    def get(self,request,*args,**kwargs):
        user_list = self.get_queryset()
        p1 = P1()  #注册分页
        data = p1.paginate_queryset(queryset=user_list,request=request,view=self)  #获取分页的数据
        ser = self.get_serializer(instance=data,many=True) #序列化
        return Response(ser.data)

  

3、 GenericViewSet(ViewSetMixin, generics.GenericAPIView)

增
    POST
    /users/
删
    DELETE
    /users/1/
改   #全部修改
    PUT
    /users/1/
    #局部修改
    patch
    /users/1/
查
    GET
    /users/
    GET
    /users/1/在GET请求的时候如果带ID说明查一条,如果不带则查所有

原始的

urls.py

urlpatterns = [

    url(r‘^index/$‘, views.IndexView.as_view()),
    url(r‘^index/(?P<pk>\d+)$‘, views.IndexView.as_view()),
]

views.py

class IndexView(views.APIView):

    def get(self,request,*args,**kwargs):
        pk = kwargs.get(‘pk‘)
        if pk:
            pass # 获取单条信息
        else:
            pass # 获取列表信息

    def post(self,request,*args,**kwargs):
        pass

    def put(self,request,*args,**kwargs):
        pass

    def patch(self,request,*args,**kwargs):
        pass

    def delete(self,request,*args,**kwargs):
                pass

  

用了GenericViewSet这种方式的时候注意url变了

urls.py

urlpatterns = [
    url(r‘^index3/$‘, views.IndexView3.as_view({‘get‘: ‘list‘,‘post‘:‘create‘})),
    url(r‘^index3/(?P<pk>\d+)/$‘, views.IndexView3.as_view({‘get‘:‘retrieve‘})),

]

views.py

class IndexView3(GenericViewSet):
    queryset = models.UserInfo.objects.all()
    serializer_class = MySerializes
    pagination_class = P1

    def list(self,request,*args,**kwargs):
        #获取列表信息
        return Response(‘...‘)

    def retrieve(self,request,*args,**kwargs):
        #获取单条数据
        return Response(‘xxx‘)

  

4、 ModelViewSet(mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet)

利用ModelViewSet增删改查不用自己写了,内部把增删改查都干了,当满足不了需求的时候我们也可以自定制

urls.py

urlpatterns = [

    url(r‘^index4/‘, views.IndexView4.as_view({‘get‘: ‘list‘,‘post‘:‘create‘})),  #获取数据和添加数据
    url(r‘^index4\.(?P<format>[a-z0-9]+)/‘, views.IndexView4.as_view({‘get‘: ‘list‘,‘post‘:‘create‘})), #.json想让页面上显示成json格式
    url(r‘^index4/(?P<pk>\d+)/‘, views.IndexView4.as_view({‘get‘: ‘retrieve‘, ‘delete‘: ‘destroy‘,‘put‘:‘partial_update‘})), #查看单条,删除,修改数据
    url(r‘^index4(?P<pk>\d+)\.(?P<format>[a-z0-9]+)/‘, views.IndexView4.as_view({‘get‘: ‘retrieve‘, ‘delete‘: ‘destroy‘,‘put‘:‘partial_update‘})),

]

views.py

注意啦:用ModelSerializer这种方法必须要用IndexSerializer(ModelSerializer)这种方式序列化
class P2(PageNumberPagination):
    page_size = 3  #每一页显示的条数
    page_query_param = ‘page‘ #获取参数中传入的页码
    page_size_query_param = ‘size‘ #获取url参数中每页显示的数据条数

    max_page_size = 5

class IndexSerializer(ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

class IndexView4(ModelViewSet):
    queryset = models.UserInfo.objects.all()
    serializer_class = IndexSerializer
    pagination_class = P2

  

自定制

基于ModelViewSet自定制

class P2(PageNumberPagination):
    page_size = 3  #每一页显示的条数
    page_query_param = ‘page‘ #获取参数中传入的页码
    page_size_query_param = ‘size‘ #获取url参数中每页显示的数据条数

    max_page_size = 5

class IndexSerializer(ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

class IndexView4(ModelViewSet):
    queryset = models.UserInfo.objects.all()
    serializer_class = IndexSerializer
    pagination_class = P2

    def list(self, request, *args, **kwargs):
        ‘‘‘获取get请求的所有‘‘‘
        pass

    def retrieve(self, request, *args, **kwargs):
        ‘‘‘查看单条数据‘‘‘
        pass
    def destroy(self, request, *args, **kwargs):
        ‘‘‘删除DELETE‘‘‘
        pass
    def create(self, request, *args, **kwargs):
        ‘‘‘添加数据POST‘‘‘
        pass
    def update(self, request, *args, **kwargs):
        ‘‘‘全部修改PUT‘‘‘
        pass
    def partial_update(self, request, *args, **kwargs):
        ‘‘‘局部修改PATCH‘‘‘
        pass

  

继承关系

三、路由

第一类:自定义路由

# http://127.0.0.1:8000/api/v1/auth/
url(r‘^auth/$‘, views.AuthView.as_view()),
# http://127.0.0.1:8000/api/v1/auth.json # 想要让页面显示json格式
url(r‘^auth\.(?P<format>[a-z0-9]+)$‘, views.AuthView.as_view()),
# http://127.0.0.1:8000/api/v1/auth/1/
url(r‘^auth/(?P<pk>\d+)/$‘, views.AuthView.as_view()),
# http://127.0.0.1:8000/api/v1/auth/1.json
url(r‘^auth/(?P<pk>\d+)\.(?P<format>[a-z0-9]+)$‘, views.AuthView.as_view()),
class AuthView(views.APIView):

    def get(self,request,*args,**kwargs):
        return Response(‘...‘)

第二类:半自动路由

url(r‘^index/$‘, views.IndexView.as_view({‘get‘:‘list‘,‘post‘:‘create‘})),
url(r‘^index\.(?P<format>[a-z0-9]+)$‘, views.IndexView.as_view({‘get‘:‘list‘,‘post‘:‘create‘})),
url(r‘^index/(?P<pk>\d+)/$‘, views.IndexView.as_view({‘get‘:‘retrieve‘,‘delete‘:‘destroy‘,‘put‘:‘update‘,‘patch‘:‘partial_update‘})),
url(r‘^index(?P<pk>\d+)\.(?P<format>[a-z0-9]+)$‘, views.IndexView.as_view({‘get‘:‘retrieve‘,‘delete‘:‘destroy‘,‘put‘:‘update‘,‘patch‘:‘partial_update‘})),

class IndexView(viewsets.ModelViewSet):
    queryset = models.UserInfo.objects.all()
    serializer_class = IndexSerializer
    pagination_class = P2

第三类:全自动路由,会自动生成四个url

router = DefaultRouter()
router.register(‘index‘,views.IndexViewSet)
urlpatterns = [
    url(r‘^‘, include(router.urls)),
]

class IndexViewSet(viewsets.ModelViewSet):
    queryset = models.UserInfo.objects.all()
    serializer_class = IndexSerializer
    pagination_class = P2

class IndexSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

四、渲染器

根据 用户请求URL 或 用户可接受的类型,筛选出合适的 渲染组件。
用户请求URL:

  • http://127.0.0.1:8000/test/?format=json
  • http://127.0.0.1:8000/test.json

用户请求头:

  • Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

1、. json

访问URL:

  • http://127.0.0.1:8000/test/?format=json
  • http://127.0.0.1:8000/test.json
  • http://127.0.0.1:8000/test/

urls.py

from django.conf.urls import url, include
from web.views import s11_render

urlpatterns = [
    url(r‘^test/$‘, s11_render.TestView.as_view()),
    url(r‘^test\.(?P<format>[a-z0-9]+)‘, s11_render.TestView.as_view()),
]

urls.py

views.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers

from rest_framework.renderers import JSONRenderer

from .. import models

class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

class TestView(APIView):
    renderer_classes = [JSONRenderer, ]

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all()
        ser = TestSerializer(instance=user_list, many=True)
        return Response(ser.data)

  

2、.表格

访问URL:

  • http://127.0.0.1:8000/test/?format=admin
  • http://127.0.0.1:8000/test.admin
  • http://127.0.0.1:8000/test/

views.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers

from rest_framework.renderers import AdminRenderer

from .. import models

class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

class TestView(APIView):
    renderer_classes = [AdminRenderer, ]

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all()
        ser = TestSerializer(instance=user_list, many=True)
        return Response(ser.data)

  

3、 Form表单

访问URL:

  • http://127.0.0.1:8000/test/?format=form
  • http://127.0.0.1:8000/test.form
  • http://127.0.0.1:8000/test/

views.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers

from rest_framework.renderers import JSONRenderer
from rest_framework.renderers import AdminRenderer
from rest_framework.renderers import HTMLFormRenderer

from .. import models

class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

class TestView(APIView):
    renderer_classes = [HTMLFormRenderer, ]

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all().first()
        ser = TestSerializer(instance=user_list, many=False)
        return Response(ser.data)

  

4、 自定义显示模板

访问URL:

  • http://127.0.0.1:8000/test/?format=html
  • http://127.0.0.1:8000/test.html
  • http://127.0.0.1:8000/test/

urls.py

from django.conf.urls import url, include
from web.views import s11_render

urlpatterns = [
    url(r‘^test/$‘, s11_render.TestView.as_view()),
    url(r‘^test\.(?P<format>[a-z0-9]+)‘, s11_render.TestView.as_view()),
]

views.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework.renderers import TemplateHTMLRenderer

from .. import models

class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

class TestView(APIView):
    renderer_classes = [TemplateHTMLRenderer, ]

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all().first()
        ser = TestSerializer(instance=user_list, many=False)
        return Response(ser.data, template_name=‘user_detail.html‘)

userdetail.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {{ user }}
    {{ pwd }}
    {{ ut }}
</body>
</html>

  

5、浏览器格式API+JSON

访问URL:

  • http://127.0.0.1:8000/test/?format=api
  • http://127.0.0.1:8000/test.api
  • http://127.0.0.1:8000/test/

views.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers

from rest_framework.renderers import JSONRenderer
from rest_framework.renderers import BrowsableAPIRenderer

from .. import models

class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
    def get_default_renderer(self, view):
        return JSONRenderer()

class TestView(APIView):
    renderer_classes = [CustomBrowsableAPIRenderer, ]

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all().first()
        ser = TestSerializer(instance=user_list, many=False)
        return Response(ser.data, template_name=‘user_detail.html‘)

  

注意:如果同时多个存在时,自动根据URL后缀来选择渲染器。

原文地址:https://www.cnblogs.com/xiaohema/p/8456967.html

时间: 2024-11-03 21:41:01

Django Restful Framework【第五篇】分页、视图、路由、渲染器的相关文章

Django-RestFrameWork之分页 视图 路由 渲染器

目录 一.分页 二.视图 三.路由 四.渲染器 一.分页 试问如果当数据量特别大的时候,你是怎么解决分页的? 方式a.记录当前访问页数的数据id 方式b.最多显示120页等 方式c.只显示上一页,下一页,不让选择页码,对页码进行加密 1.基于limit offset 做分页 from rest_framework.pagination import LimitOffsetPagination 1 urlpatterns = [ 2 url(r'^admin/', admin.site.urls)

django restful framework 一对多方向更新数据库

目录 django restful framework 序列化 一 . 数据模型: models 二. 序列化: serializers 三, 视图: views 四, 路由: urls 五. 测试 : test django restful framework 序列化 案例: 一个网域domain可以绑定多台服务器主机assets, 但是一台服务器只能绑定一个网域. 数据模型之间关系适用于一对多. 一 . 数据模型: models 定义 assets 模型:apps/assets/models

3- vue django restful framework 打造生鲜超市 - model设计和资源导入

3- vue django restful framework 打造生鲜超市 - model设计和资源导入 使用Python3.6与Django2.0.2(Django-rest-framework)以及前端vue开发的前后端分离的商城网站 项目支持支付宝支付(暂不支持微信支付),支持手机短信验证码注册, 支持第三方登录.集成了sentry错误监控系统. 本小节内容: model设计与资源引入 资源初始化 数据库设计,数据表结构 新建虚拟环境 mkvirtualenv -p=D:\softEnv

Django Restful Framework【第三篇】认证、权限、限制访问频率

一.认证 认证请求头 views.py #!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.authentication import BaseAuthentication from rest_framework.permissions import

Django Rest Framework源码剖析(八)-----视图与路由

一.简介 django rest framework 给我们带来了很多组件,除了认证.权限.序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使用者而言不同的视图具有不同的功能,这样我们可以根据需求定制自己视图.以下是官网传送门:http://www.django-rest-framework.org/api-guide/views/ 在之前的文章中,由于参杂了权限.认证等(如果不了解请看博客的以前的文章),但在本章中基本可以不使用,所进使

Django REST framework 第五章 Relationships &amp; Hyperlinked APIs

到目前为止,API内部的关系是使用主键来代表的.在这篇教程中,我们将提高API的凝聚力和可发现性,通过在相互关系上使用超链接. Creating an endpoint for the root of our API 现在,我们已经有了snippets和users的终端,但是没有一个单独的终端指向我们的API.使用之前常规的FBV方式和@api_view装饰器创建一个.在你的app的views文件内 from rest_framework.decorators import api_view f

Django Restful Framework

你在浏览器中输入了一个地址的时候发生了什么事情? 1.HOST 2.DNS 3.HTTP/HTTPS协议 发送一个协议 4.进入了实现了WSGI协议的服务器(wsgiref uwsgi(C语言实现,多线程,多进程,PHP,TOMCAT)) 5.请求进入Django 6. 前后端不分离:中间件->路由分发->对应的视图函数->找到模板,渲染数据-> 返回模板的字符串 前后端分析:中间件->路由分发->返回JSON数据 Django源代码解读 graph TD A[路由匹配

C#使用Xamarin开发可移植移动应用进阶篇(7.使用布局渲染器,修改默认布局),附源码

前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 本篇..基本可以算是Xamarin在应用开发过程中的核心了..真的很很很重要.. 想学习的..想用的..建议仔细阅读..嗯..打酱油的 ..快速滑倒下面点个推荐 - - 哈哈哈... 今天的学习内容? 也只讲一个,关于Xamarin.Forms针对各个平台如何进行可定制化的布局操作. 也就是针对某个平台的细颗

Django Restful Framework【第四篇】版本、解析器、序列化和请求数据验证

一.版本 程序也来越大时,可能通过版本不同做不同的处理 没用rest_framework之前,我们可以通过以下这样的方式去获取. class UserView(APIView): def get(self,request,*args,**kwargs): version = request.query_params.get('version') print(version) if version=='v1': #如果版本是v1 ret = { 'code':111, 'msg':'版本一的内容'