5 解析器、url路由控制、分页、渲染器和版本

1 数据解析器

1 什么是解析器

相当于request 中content-type

对方传什么类型的数据,我接受什么样的数据;怎样解析

 无论前面传的是什么数据,都可以解开

例如:django不能解析json数据,restfrmaework可以解析

django只能解开,urlcode的数据

添加一本书籍,传json数据

 

2 5种解析器

 

 j

支持4个

 

解析二进制文件用

 

 常用的2个解析器

 

默认使用3个

3 JSONParser解析器

反序列化 json--dict

 

如何引用,

走我的,只能解析一种JSON

 

test

 现在只能解析1 中 json

4 FormParser解析器

添加form解析器

5 Code与笔记

 笔记

7 解析器-----数据解析器
    from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser
    parser_classes = [JSONParser,FormParser]

view

from rest_framework.parsers import JSONParser
from rest_framework.parsers import FormParser

class BookView(APIView):
    # authentication_classes = [TokenAuth,]  # 认证组件
    # permission_classes =[]  # 权限组件
    # throttle_classes = []  # 频率组件

    # parser_classes = [JSONParser]
    parser_classes = [JSONParser,FormParser]

    def get(self,request):
        book_list = Book.objects.all()
        bs = BookModelSerializers(book_list,many=True,context={'request':request})
        return Response(bs.data)  # Response继承HttpResponse

    def post(self,request):
        # post请求的数据
        print(request.data)
        # self.dispatch
        bs = BookModelSerializers(data=request.data,context={'request':request})
        if bs.is_valid():
            print(bs.validated_data)
            bs.save()  # create方法
            return Response(bs.data)
        else:
            return Response(bs.errors)

2 url控制

 1.针对 视图3 viewset

 最后一种方式,有4条url

4条url

 

 url 有重复的内容,如何优化

 2.官方文档

注册下

自动生成url的路径

 3. 如何生成4条url

这4条是帮我生成的

test

4.code

路由控制
    针对:
         url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),
         url(r'^authors/(?P<pk>d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailauthor"),
       
         class AuthorModelView(viewsets.ModelViewSet):
                queryset = Author.objects.all()
                serializer_class = AuthorModelSerializers
url 配置
from rest_framework import routers
routers = routers.DefaultRouter()
routers.register('authors',views.AuthorView)

urlpatterns = [
... re_path(
'^',include(routers.urls)),
... ]

3 分页器

django有分页

rest 也有分页

1.简单分页

(1)源码

 

page_size   每页显示多少条数据
page_query_param 分页结果集中的页码
page_size_query_param 每页返回的结果数
max_page_size 
    将其设置为整数,以限制客户机可能请求的最大页面大小
    Only relevant if 'page_size_query_param' has also been set

(2)全局配置

 

 test

(3)局部配置

 

每页显示2个
参数 page
page=1 &size = 3
第一页默认2条,临时改成3条
最大不能超过3个,限制临时size

先分页,分完后,进行序列化

 

2.偏移分页(不常用)

(1) 源码

default_limit 
limit_query_param  每页返回的结果数。
offset_query_param 返回结果的初始索引

 (2)自定义

默认显示1

 

(3)test

在此基础后,偏移1

拿到第二个,类似于 相对路径

3.视图3 Viewset:一句话分页

(1)对于视图modelviewset,如何分页?

只需要加1个即可,源码里面有分页

 

 

谁的self.paginate_queryset(queryset)

 找pagination_class即可

 (2)以后,3句话就完成分页了

(3)test

 

4.代码

views

from rest_framework.pagination import PageNumberPagination  # 简单分页
from rest_framework.pagination import LimitOffsetPagination  # 偏移分页

class MyPageNumberPagination(PageNumberPagination):
    page_size = 1
    page_query_param = 'page'
    page_size_query_param = 'size'
    max_page_size = 3

class MyLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 1


class BookView(APIView):

    def get(self,request):
        book_list = Book.objects.all()

        # 分页
        pnp = MyPageNumberPagination()
        # pnp = LimitOffsetPagination()
        book_age = pnp.paginate_queryset(book_list,request,self)

        bs = BookModelSerializers(book_age,many=True,context={'request':request})
        return Response(bs.data)  # Response继承HttpResponse

    def post(self,request):
        # post请求的数据
        print(request.data)
        # self.dispatch
        bs = BookModelSerializers(data=request.data,context={'request':request})
        if bs.is_valid():
            print(bs.validated_data)
            bs.save()  # create方法
            return Response(bs.data)
        else:
            return Response(bs.errors)


# Author
# 视图三部曲,最后一种
from rest_framework import viewsets

class AuthorView(viewsets.ModelViewSet):
    queryset = Author.objects.all()
    serializer_class = AuthorModelSerializers
    pagination_class = MyPageNumberPagination

settings

REST_FRAMEWORK = {
    # Pagination
    'PAGE_SIZE': 1,
}

 4 Response响应器

1.之前提到的

https://www.cnblogs.com/venicid/p/11231983.html#_label3_1

2、源码

Response  只是一堆数据

HTTPResponse 只能放字符串

 用浏览器的话,默认是用户,给个html页面

方便用户操作

后续可以delete请求,只有json数据的话,没有

 

实质还是请求的还是数据

 实质:json数据

5 渲染器

1.demo

主urls

from django.contrib import admin
from django.urls import path,re_path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/',include('api.urls'))
]

api.urls

from django.urls import path,re_path,include

from api.views import course
urlpatterns = [
    re_path('^course',course.CourseViews.as_view())
]

view

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer

from django.shortcuts import HttpResponse

class CourseViews(APIView):

    # renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
    renderer_classes = [JSONRenderer]

    def get(self,request,*args,**kwargs):
        self.dispatch   # 快速找dispatch
        return Response('course...')  # 出错了,没有在app中注册 rest_framework
        # return HttpResponse('course...')

settings

INSTALLED_APPS = [
    ...
    'rest_framework',
]

...
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer',
                                 'rest_framework.renderers.BrowsableAPIRenderer'],
}

2.rest_framework如何渲染的

 

 

3. 渲染器 JSONRenderer和BrowsableAPIRenderer

一般情况用json即可

 

restframe实质:把你的json数据嵌套到html中显示

 

4.全局配置

 源码

我的settings设置

6 版本 /api/v1/

1.源码剖析

 

5种支持的版本传参 

继承BaseVersioning

 5个类,2个不用

参数配置

2.方法1(不推荐)

(1)源码

 实质:django中request的get方法

version参数,与默认

只能指定 v1 v2

 

(2)局部配置

urls

(3)全局配置

(4)test

不同verison 能拿到不同的版本 

  

没有允许的版本

 

默认的

3.方法2 URLPathVersioning (推荐版本)

(1)局部配置

 version会传到kwargs

 

(2)全局配置过(推荐版本)

 

url

 (3)test

 

4. Code和笔记

1、笔记

    2. 版本 
        原理:要了解
        使用:
            1. 添加配置
                REST_FRAMEWORK = {
                    .... 
                    'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
                    'ALLOWED_VERSIONS':['v1','v2'], # 允许的版本
                    'VERSION_PARAM':'version', # 参数
                    'DEFAULT_VERSION':'v1', # 默认版本
                    ....
                }

            2. 设置路由 
                
                s9luffycity/urls.py
                    urlpatterns = [
                        #url(r'^admin/', admin.site.urls),
                        url(r'^api/(?P<version>w+)/', include('api.urls')),
                    ]
                
                api/urls.py 
                    urlpatterns = [
                        url(r'^course/$', course.CourseView.as_view()),
                    ]
            
            3. 获取版本 
                request.version 获取版本  

 2、代码

主url

from django.contrib import admin
from django.urls import path,re_path,include

urlpatterns = [
    path('admin/', admin.site.urls),

    # re_path('api/(?P<version>[v1|v2]+)/',include('api.urls')),
    re_path('api/(?P<version>w+)/',include('api.urls'))
]
View Code

api.url

from django.urls import path,re_path,include

from api.views import course
urlpatterns = [
    re_path('^course',course.CourseViews.as_view())
]
View Code

api.views.course

from django.shortcuts import HttpResponse

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer

from rest_framework.versioning import QueryParameterVersioning
from rest_framework.versioning import URLPathVersioning


class CourseViews(APIView):

    # versioning_class = QueryParameterVersioning
    # versioning_class = URLPathVersioning  # 推荐版本

    # renderer_classes = [JSONRenderer]   # 一般情况使用json即可
    # renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
    def get(self,request,*args,**kwargs):  # version会传到kwargs
        # self.dispatch   # 快速找dispatch
        print(request.version)
        return Response('course...')  # 出错了,没有在app中注册 rest_framework
        # return HttpResponse('course...')
View Code

settings

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer',
                                 'rest_framework.renderers.BrowsableAPIRenderer'],
    # Versioning
    'DEFAULT_VERSION': 'v1',   # 默认的版本
    'ALLOWED_VERSIONS': ['v1','v2'],  # 允许的版本
    'VERSION_PARAM': 'version',   # 参数

    # 方式1
    # from rest_framework.versioning import QueryParameterVersioning
    'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.QueryParameterVersioning',

    # 方式2:推荐
    # from rest_framework.versioning import URLPathVersioning
    # 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
}
View Code
原文地址:https://www.cnblogs.com/venicid/p/11308961.html