一、url控制

基本路由写法:最常用

from django.conf.urls import url
from django.contrib import admin
from app01 import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^books/', views.Books.as_view()),
url(r'^book/', views.Book.as_view()),
url(r'^login/', views.Login.as_view()),
]

第二种写法:继承ModelViewSet

基于mixins来封装的视图就是使用了继承ModelViewSet,然后改写路由:

from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^publish/$', views.PublishView.as_view({'get':'list','post':'create'})),
url(r'^publish/(?P<pk>\d+)/$', views.PublishView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
]

第三种写法:(自动生成路由,必须继承ModelViewSet)

# SimpleRouter 自动生成两条路由

实现过程:

tips:使用python的manage.py的shell环境进行快速添加数据用于测试:

pycharm>>Terminal:

python3 manage.py shell
>>> from app01 import models
>>> models.Publish.objects.create(name='北方出版社',addr='北京')
<Publish: Publish object>
>>> models.Publish.objects.create(name='长江出版社',addr='湖北')
<Publish: Publish object>
>>> models.Publish.objects.create(name='东方出版社',addr='唐朝')
<Publish: Publish object>
from django.shortcuts import render
from rest_framework.response import Response # Create your views here.
from app01 import models
from app01.MySer import PublishSer
from rest_framework.viewsets import ModelViewSet class PublishDetails(ModelViewSet):
queryset = models.Publish.objects.all()
serializer_class = PublishSer

views.py代码

from django.conf.urls import url, include
from django.contrib import admin
from app01 import views from rest_framework.routers import SimpleRouter,DefaultRouter
router = SimpleRouter()
router.register('publish', views.PublishDetails) urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include(router.urls)),
]

urls.py代码

from rest_framework import serializers
from app01 import models
class PublishSer(serializers.ModelSerializer):
class Meta:
model = models.Publish
fields = "__all__"

MySer序列化类文件

from django.db import models

# Create your models here.
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=64)

models.py文件

测试,输入一个错误的路由,查看自动生成2条路由:

# DefaultRouter 自动生成四条路由

二、解析器

前端不同的数据格式请求,后端解析得到的结果:

json格式:
前端:(使用postman发送请求,json格式)

后端:(打印request.data数据)

form-data格式:

urlencoded格式:

小结:可以看出

json格式数据发送,后端解析出来的数据为:<class 'dict'>

form-data和urlencoded格式数据发送,后端解析出来的数据为:QueryDict对象,<class 'django.http.request.QueryDict'>

解析器介绍:

所谓解析器,就是前端传过来的数据,后端可以解析,从request.data中取出来,默认的解析器配置是三种编码格式都可以取

解析器的作用:

根据请求头(content-type)选择对应的解析器对请求体内容进行处理,有application/json,x-www-form-urlencoded,form-data等格式

设置解析器就可以控制前端传过来的数据类型进行限制,比如说我只能解析json格式的数据,那么前端必须给我传json数据我才能拿到

三种编码格式:urlencoded,formdata,json
-urlencoded:在body体中的格式是:name=xxx&age=18&wife=liyitong
-formdata:在body体中的格式数据部分跟文件部分有区分
-json格式:在body体中就是json格式

解析器的使用:

(实际就是通过配置解析器,让后端只接收某一种格式的请求数据类型,这样后端只能解析该类型数据,其它类型的请求都会无效,当然设置一种也可以设置多种)

局部使用:

测试:

全局使用:

 先了解一下默认解析三种格式的设置代码:

全局设置:

在setting中配置:
REST_FRAMEWORK = {
"DEFAULT_PARSER_CLASSES":[
'rest_framework.parsers.JSONParser',
]
}

三、响应器:

响应器的作用:

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

响应器的使用:

-from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
-不用动,就用全局配置即可
-全局使用:
-在setting中配置
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
]
-局部使用:
-在视图类中配置:
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]

响应器的内置渲染器:

显示json格式:JSONRenderer

访问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/

默认显示格式:BrowsableAPIRenderer(可以修改它的html文件)

访问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/

表格方式:AdminRenderer

访问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/

form表单方式:HTMLFormRenderer

访问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/

四、版本控制

restful规范里,提出过版本的概念,也就是说版本控制就是相对于接口而言,它有多个版本,就好像应用程序、手机app都会更新版本一样,会修改更新接口文件,这时候就不能在原接口进行修改更新,应该另起一个接口作为版本2(假设为v2)来提供给用户使用,原来的版本可能是v1,那么v1和v2版本提供给外界的控制,就是版本控制。

通过路由拼接版本号或者放入请求头中的途径来获取对应版本号的接口,进行请求。

from rest_framework.versioning import QueryParameterVersioning,AcceptHeaderVersioning,NamespaceVersioning,URLPathVersioning

#基于url的get传参方式:QueryParameterVersioning------>如:/users?version=v1
#基于url的正则方式:URLPathVersioning------>/v1/users/
#基于 accept 请求头方式:AcceptHeaderVersioning------>Accept: application/json; version=1.0
#基于主机名方法:HostNameVersioning------>v1.example.com
#基于django路由系统的namespace:NamespaceVersioning------>example.com/v1/users/

全局使用:

-在setting中配置:
'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
'DEFAULT_VERSION': 'v1', # 默认版本(从request对象里取不到,显示的默认值)
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version' # URL中获取值的key
-路由需要修改
-url(r'^(?P<version>[v1|v2]+)/test/', views.Test.as_view()),

局部使用:

在视图类中就可以通过:request.version取出当前访问哪个版本,相应的取执行相应版本的代码

五、DRF分页器

前戏:批量创建多条数据用于测试分页:

url(r'^pagetest/', views.PaginationTest.as_view()),
# views.py

class PaginationTest(APIView):

    # 批量创建publish记录,用于测试分页
def post(self,request):
pub_l = []
for i in range(1000):
pub_l.append(models.Publish(name='出版社[%s]' % (i+1), addr='地址[%s]' % (i+1)))
models.Publish.objects.bulk_create(pub_l)
return Response('批量创建成功')

常规分页

url(r'^pagetest/', views.PaginationTest.as_view()),
# 视图类

from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
from app01.MySer import PublishSer class PaginationTest(APIView):
# 批量创建publish记录,用于测试分页
def post(self,request):
pub_l = []
for i in range(1000):
pub_l.append(models.Publish(name='出版社[%s]' % (i+1), addr='地址[%s]' % (i+1)))
models.Publish.objects.bulk_create(pub_l)
return Response('批量创建成功') def get(self, request, *args, **kwargs):
# 拿到所有数据
publish_list = models.Publish.objects.all()
# 实例化出page对象
page = PageNumberPagination()
# ================ page相关参数配置开始 ================ #
# # 每页显示10条,也可以在settings.py中添加全局配置('PAGE_SIZE': 10 )
page.page_size = 10
# # 设置每页条数的拼接key(默认为size)
page.page_size_query_param = 'size0'
# # 控制每页最大显示条数:(这个控制仅限制于路径后拼接设置size0=1000后,对其进行限制)
page.max_page_size = 30
# # 设置定位的页数的拼接key(默认是page)
page.page_query_param = 'page0'
# ================ page相关参数配置结束 ================ #
# 对数据进行分页处理:
ret_page = page.paginate_queryset(publish_list, request, self)
# 序列化
pub_ser = PublishSer(instance=ret_page, many=True) return Response(pub_ser.data)

也可以在全局配置每页显示条数:

测试:

偏移分页

偏移分页与普通分页使用基本相同,类不同,配置的参数名称不同

# 偏移分页:
def get(self, request, *args, **kwargs):
# 拿到所有数据
publish_list = models.Publish.objects.all()
# 实例化出page对象
page = LimitOffsetPagination()
# ================ page相关参数进行配置开始 ================ #
# # 从标杆位置往后取几个,比如指定取10个
page.default_limit = 10
# # 拼接key值自定义
# 拿几条记录的key值自定义
page.limit_query_param = 'limit0'
# 标杆值(起始位置),从设置的offset0值那个位置往后拿limit0值的记录
page.offset_query_param = 'offset0'
# # 设置最大取10条
page.max_limit = 20
# ================ page相关参数进行配置结束 ================ #
# 对数据进行分页处理:
ret_page = page.paginate_queryset(publish_list, request, self)
# 序列化
pub_ser = PublishSer(instance=ret_page, many=True) return Response(pub_ser.data)

补充:get_paginated_response的使用

return Response(pub_ser.data) 替换成 return page.get_paginated_response(pub_ser.data)

作用测试图:(此方法主要用于游标分页中,因为游标分页并不能指定第几页第几页,只有上一页和下一页)

cursor游标分页

# 游标分页:
def get(self, request, *args, **kwargs):
# 拿到所有数据
publish_list = models.Publish.objects.all()
# 实例化出page对象
page = CursorPagination()
# ================ page相关参数进行配置开始 ================ #
# # 每页显示条数
page.page_size = 5
# # 查询的key值自定义,默认是cursor,无需更改
page.cursor_query_param = 'cursor'
# 游标分页会将记录进行排序,然后根据排序的记录进行分页显示,设置排序依据
page.ordering = 'id'
# ================ page相关参数进行配置结束 ================ #
# 对数据进行分页处理:
ret_page = page.paginate_queryset(publish_list, request, self)
# 序列化
pub_ser = PublishSer(instance=ret_page, many=True)
# 如果使用Response返回数据,就不知道怎么定位上一页和下一页了
# return Response(pub_ser.data)
# 使用get_paginated_response,返回结果
return page.get_paginated_response(pub_ser.data)

游标分页的cursor后面的值我们是不知道的,所以拼不出来:

游标分页特点:它是一种加密分页,只能看上一页和下一页,速度快

Django框架深入了解_04(DRF之url控制、解析器、响应器、版本控制、分页)的更多相关文章

  1. DRF url控制 解析器 响应器 版本控制 分页(常规分页,偏移分页,cursor游标分页)

    url控制 第二种写法(只要继承了ViewSetMixin) url(r'^pub/$',views.Pub.as_view({'get':'list','post':'create'})), #获取 ...

  2. DRF 的 版本,解析器,与序列化

    DRF 的 版本,解析器,与序列化 补充 配置文件中的 类的调用: (字符串) v1 = ["view.xx.apth.Role","view.xx.apth.Role& ...

  3. drf 解析器,响应器,路由控制

    解析器 作用: 根据请求头 content-type 选择对应的解析器对请求体内容进行处理. 有application/json,x-www-form-urlencoded,form-data等格式 ...

  4. drf的组件和解析器

    drf的序列化组件: 1. 用途: 把python中的对象,转成json格式字符串 2. 使用步骤1: 写一个类继承Serializer或者ModelSerializer 举例(类中选取字段进行序列化 ...

  5. Django框架深入了解_03(DRF之认证组件、权限组件、频率组件、token)

    一.认证组件 使用方法: ①写一个认证类,新建文件:my_examine.py # 导入需要继承的基类BaseAuthentication from rest_framework.authentica ...

  6. Django框架深入了解_02(DRF之序列化、反序列化)

    序列化:将Python对象准换成json格式的字符串,反之即为反序列化 DRF的序列化使用过程: 使用drf的序列化组件 -1 新建一个序列化类继承Serializer -2 在类中写要序列化的字段 ...

  7. Django框架 之 admin管理工具(源码解析)

    浏览目录 单例模式 admin执行流程 admin源码解析 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在 ...

  8. Django框架rest_framework中APIView的as_view()源码解析、认证、权限、频率控制

    在上篇我们对Django原生View源码进行了局部解析:https://www.cnblogs.com/dongxixi/p/11130976.html 在前后端分离项目中前面我们也提到了各种认证需要 ...

  9. django框架介绍

    主要内容 1.        Django框架发展 2.        Django架构,MTV模式 3.        开发流程 4.        开发实例——Poll python下各种框架 一 ...

随机推荐

  1. 48、Spark SQL之与Spark Core整合之每日top3热点搜索词统计案例实战

    一.概述 1.需求分析 数据格式: 日期 用户 搜索词 城市 平台 版本 需求: 1.筛选出符合查询条件(城市.平台.版本)的数据 2.统计出每天搜索uv排名前3的搜索词 3.按照每天的top3搜索词 ...

  2. 洛谷P4408 逃学的小孩

    题目 求树的直径,因为任意两个居住点之间有且只有一条通路,所以这是一棵树. 根据题意父母先从C去A,再去B,或者反过来. 我们一定是要让A到B最大,也要让C到A和B的最小值最大. AB最大一定就是直径 ...

  3. pycharm无法识别自己的文件夹的程序

    网上找教程折腾了半天也没解决,然后我换了一下文件夹名称…… 文件夹名称不能用数字开头,否则识别不出来.

  4. win10 自带计算器删除了怎么办

    win+S后输入Powershell,以管理员身份运行后,使用下面的命令:重要的说三遍:以管理员身份运行!以管理员身份运行!以管理员身份运行!Get-AppxPackage *calculator* ...

  5. C++之宏、extern关键字与多线程

    理解C++ 宏 1.特殊字符 考虑下面的需求,程序中多处使用文本字符串.我们知道文本字符串前后都要加上双引号,我很讨厌输入双引号.有没有好的办法呢?根据常识,使用下面的宏: #define Str(x ...

  6. go 牛顿法开平方

    func main() { fmt.Println(sqrt(3)) } func sqrt(x float64)float64{ z := x for i := 0; i < 10 ; i++ ...

  7. CSS背景和精灵图

    如何设置背景图片? 1.在CSS中有个叫做background-image:url():的属性,就是专门用于设置背景图片的. 2.注意点: 1)图片的地址必须放在url()中,图片的地址可以是本地的地 ...

  8. Python之Lambda与三元运算

    Python之Lambda与三元运算 Lambda 运算 概念:是指一类无需定义标识符(函数名)的函数或者子程序.特点:匿名函数不使用def定义函数,使用lambda来创建匿名函数1.lambda只是 ...

  9. SymPy解方程的实现

    https://www.cnblogs.com/zgyc/p/6277562.html SymPy完全是用Python写的,并不需要外部的库 原理: 单纯用语言内置的运算与变量解决的是,由值求结果.如 ...

  10. 初探Android逆向:通过游戏APP破解引发的安全思考

    如今移动互联网已经完全融入到我们的生活中,各类APP也是层出不穷,因此对于安卓APP安全的研究也尤为重要.本文通过对一款安卓APP的破解实例,来引出对于APP安全的探讨.(本人纯小白,初次接触安卓逆向 ...