路由控制

-基本路由写法:咱们一直写的
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^books/$', views.BookView.as_view()),
url(r'^books/(?P<pk>\d+)$', views.BookDetailView.as_view()),
]
class BookView(APIView):

    def get(self, request):
book_list = models.Book.objects.all()
bs = BookSerializers(book_list, many=True)
return Response(bs.data) def post(self, request):
# 添加一条数据
print(request.data) bs=BookSerializers(data=request.data)
if bs.is_valid():
bs.save() # 生成记录
return Response(bs.data)
else: return Response(bs.errors) class BookDetailView(APIView):
def get(self,request,pk):
book_obj=models.Book.objects.filter(pk=pk).first()
bs=BookSerializers(book_obj,many=False)
return Response(bs.data)
def put(self,request,pk):
book_obj = models.Book.objects.filter(pk=pk).first() bs=BookSerializers(data=request.data,instance=book_obj)
if bs.is_valid():
bs.save() # update
return Response(bs.data)
else:
return Response(bs.errors)
def delete(self,request,pk):
models.Book.objects.filter(pk=pk).delete() return Response("")
-第二种写法(必须继承只要继承了ViewSetMixin):
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
  获取所有出版社,以及新增数据
url(r'publish/$',views.PublishView.as_view({'get':'list','post':'create'})),
  获取单个数据,删除单个数据,更新单个数据
url(r'publish/(?P<pk>\d+)$',views.PublishView.as_view({'get':'retrieve','delete':'destroy','put':'update'}))
]

注意:

1.'get','post','delete','put',''是method提交数据的方法,list,create,retrieve,destroy,update是内部对应的方法,可以在视图类中重写这些方法

2.五个方法,两个路由

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

serializer.py

from django.db import models

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

models.py

from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
#源码

class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass

1.ModelViewSet中继承了ViewSetMixin所有继承了GenericViewSet,GenericViewSet继承了ViewSetMixin

2.ViewSetMixin中action必须要传值,不然会报错(action也就是传入的字典)

3.

4.有名分组,传入的关键字必须是pk,这个内部固定死的

完美分割线

通过format=json获取到json格式的字符串
也有另外一种方式(就是需要配置路由)
url(r'^publish\.(?P<format>\w+)$', views.PublishView.as_view({'get':'list','post':'create'}))

-第三种(自动生成路由,必须继承ModelViewSet):
-SimpleRouter 自动生成两条路由
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('publish',views.PublishView) urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'^publish/$',views.PublishView.as_view({'get':'list','post':'create'})),
# url(r'^publish/(?P<pk>\d+)',views.PublishView.as_view({'get':'retrieve','delete':'destroy','put':'update'})),
url(r'',include(router.urls))
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
   -DefaultRouter自动生成四条路由
from django.conf.urls import url,include
from app01 import views
from rest_framework import routers
router=routers.DefaultRouter()
# 两个参数,一个是匹配的路由,一个是视图中写的CBV的类
router.register('publish',views.PublishView)
urlpatterns = [
# http://127.0.0.1:8000/publish/format=json(渲染器通过这个判断,返回渲染的页面)
# url(r'^publish/', views.PublishView.as_view({'get':'list','post':'create'})),
# http://127.0.0.1:8000/publish.json(渲染器通过这个判断,返回渲染的页面)
# url(r'^publish\.(?P<format>\w+)$', views.PublishView.as_view({'get':'list','post':'create'})), # 可以用 以下方式访问
# 1 http://127.0.0.1:8000/publish/
# 2 http://127.0.0.1:8000/publish.json
# 3 http://127.0.0.1:8000/publish/3
# 4 http://127.0.0.1:8000/publish/3.json
url(r'',include(router.urls))
]
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers

解析器

-在取某个值之前,先反射看一下有没有,有的话直接返回,如果没有,再去执行获取这个值的方法
一开始request.data去获取值,先看看你之前是否用过,用过直接返回,没用过就去body取出做解析,所以入口是request.data
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
from rest_framework.request import Request
class Test(APIView):
parser_classes = [JSONParser,]
def post(self,request):
print(request.data)
print(type(request.data))
return Response

从Request中找到data

源码

parser就是我在视图类中parser_classes=[JSONParser,]JSONParser类产生的对象

然后调用parser对象方法进行解析(以下是在Requst类中的_parser方法中找到的)

这些类中都有一个parse方法,称之为鸭子类型,

不管返回的是谁的对象,直接调用它们类中的parser方法传入该传的参数就能做解析

Request类中_parser中的parser = self.negotiator.select_parser(self,self.parsers)中的negotiator是Request初始化对象的时候产生并传入值,而Request是在APIVeiw 的dispatch中初始化对象的

Request类中_parser中的parser = self.negotiator.select_parser(self,self.parsers)中的self.parsers

是Request初始化对象的时候产生并传入值,而Request是在APIVeiw 的dispatch中初始化对象的

而parsers = self.get_parsers()中的get_parsers,就是传入视图中定义的列表中的类名

然后parser = self.negotiator.select_parser(self,self.parsers)中的self.parsers是所有解析器,然后选择一个返回,根据Request对象request请求编码格式传入

小总结:

-解析器(一般不需要动,项目最开始全局配置一下就可以了) 
-作用是控制我的视图类能够解析前端传过来的格式是什么样的
-全局使用:
在setting中配置:
REST_FRAMEWORK = {
"DEFAULT_PARSER_CLASSES":[
'rest_framework.parsers.JSONParser',
] }
-全局使用:
-在视图类中:
parser_classes=[JSONParser,] -源码流程:
-当调用request.data的时候去执行解析方法----》根据传过来的编码方式选择一个解析器对象,调用解析器对象的parser方法完成解析

响应器

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

版本控制

在restful规范当中,版本号可以放在路径当中,还可以放在请求头当中

直接使用内置,

内置的版本控制类

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/

局部使用

#在CBV类中加入
versioning_class = URLPathVersioning

四 全局使用

REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.QueryParameterVersioning',
'DEFAULT_VERSION': 'v1', # 默认版本(从request对象里取不到,显示的默认值)
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version' # URL中获取值的key
}

示例

基于正则的方式:

from django.conf.urls import url, include
from web.views import TestView urlpatterns = [
url(r'^(?P<version>[v1|v2]+)/test/', TestView.as_view(), name='test'),
]

urls.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import URLPathVersioning class TestView(APIView):
versioning_class = URLPathVersioning def get(self, request, *args, **kwargs):
# 获取版本
print(request.version)
# 获取版本管理的类
print(request.versioning_scheme) # 反向生成URL
reverse_url = request.versioning_scheme.reverse('test', request=request)
print(reverse_url) return Response('GET请求,响应内容')

views.py

        # 基于django内置,反向生成url
from django.urls import reverse
url2=reverse(viewname='ttt',kwargs={'version':'v2'})
print(url2)

分页

批量添加(了解)

class PublishView(APIView):
versioning_class = URLPathVersioning
parser_classes = [JSONParser,] def get(self,request,*args,**kwargs):
li = []
for i in range(100):
li.append(models.Publish(name='%s出版社'%i,city='%s城市'%i))
models.Publish.objects.bulk_create(li)
return Response()
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^(?P<version>[v1|v2]+)/test/', views.PublishView.as_view())
]

简单分页(查看第n页,每页显示n条)

# 一 基本使用:url=url=http://127.0.0.1:8000/pager/?page=2&size=3,size无效
from rest_framework.versioning import URLPathVersioning
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
class Page(APIView):def get(self,request,*args,**kwargs): #查询出所有的数据
ret = models.Publish.objects.all()
#实例化产生一个普通分页对象
page=PageNumberPagination()
#ret_page是返回分页之后的数据(列表存放着我一个个数据),已经是分好页了
ret_page = page.paginate_queryset(ret,request,self)
#序列化
pub_ser = serializer.PublishSerializers(ret_page,many=True)
#去settings中配置每页显示多少条
return Response(pub_ser.data)
REST_FRAMEWORK = {
"DEFAULT_PARSER_CLASSES":[
'rest_framework.parsers.JSONParser',
], 'PAGE_SIZE':2 #表示每页显示两条 }
自定义页数

偏移分页(在第n个位置,向后查看n条数据)

# http://127.0.0.1:8000/pager/?offset=4&limit=3
from rest_framework.pagination import LimitOffsetPagination
# 也可以自定制,同简单分页
class Pager(APIView):
def get(self,request,*args,**kwargs):
# 获取所有数据
ret=models.Book.objects.all()
# 创建分页对象
page=LimitOffsetPagination()
# 在数据库中获取分页的数据
page_list=page.paginate_queryset(ret,request,view=self)
# 对分页进行序列化
ser=BookSerializer1(instance=page_list,many=True)
# return page.get_paginated_response(ser.data)
return Response(ser.data)

CursorPagination(加密分页,只能看上一页和下一页,速度快)

思考:不重写类,修改类属性?

from rest_framework.pagination import CursorPagination
# 看源码,是通过sql查询,大于id和小于id
class Pager(APIView):
def get(self,request,*args,**kwargs):
# 获取所有数据
ret=models.Book.objects.all()
# 创建分页对象
page=CursorPagination()
page.ordering='nid'
# 在数据库中获取分页的数据
page_list=page.paginate_queryset(ret,request,view=self)
# 对分页进行序列化
ser=BookSerializer1(instance=page_list,many=True)
# 可以避免页码被猜到
return page.get_paginated_response(ser.data)

小总结:

-分页
1 常规分页
-基本使用:
-page=PageNumberPagination实例化产生对象
-返回值=page.paginate_queryset(ret,request,self):ret是要分页的所有数据,
-再序列化,序列化该返回值
-四个参数
#每页显示多少条
page.page_size=3
#查询指定查询哪一页的key值
page.page_query_param='xxx' #前端控制每页显示多少条的查询key值比如size=9,表示一页显示9条
page.page_size_query_param='size'
#控制每页最大显示多少,size如果传100,最多也是显示10
page.max_page_size=10
2 偏移分页
-基本使用:
-page=LimitOffsetPagination实例化产生对象
-返回值=page.paginate_queryset(ret,request,self):ret是要分页的所有数据,
-再序列化,序列化该返回值 -四个参数:
#从标杆位置往后取几个,默认取3个,我可以指定
page.default_limit=3
#每次取得条数
page.limit_query_param='limit'
#标杆值,现在偏移到哪个位置,如果offset=6 表示当前在第6条位置上,往后取
page.offset_query_param='offset'
#最大取10条
page.max_limit=10
3 cursor游标方式
-基本使用:
-page=CursorPagination实例化产生对象
-返回值=page.paginate_queryset(ret,request,self):ret是要分页的所有数据,
-再序列化,序列化该返回值 -三个参数:
#每页显示的大小
page.page_size=3
#查询的key值
三种编码格式:urlencoded,formdata,json
-urlencoded:在body体中的格式是:name=lqz&age=18&wife=liuyifei
-formdata:在body体中的格式数据部分跟文件部分有区分
-json格式:在body体中就是json格式
         page.cursor_query_param='cursor'
# 按什么排序
page.ordering='id'
-注意:get_paginated_response:调用这个方法返回的数据中会有总条数,上一页地址,下一页地址

url,解释器,响应器,版本控制,分页的更多相关文章

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

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

  2. DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

  3. day91 DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

  4. day 89 DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

  5. jnhs 无法提交断点LineBreakpoint hibernate4CURD : -1, 原因是: 找不到 URL 'file:/E:/版本控制/Design-java/hibernate4CURD/' 的源根目录。请验证项目源的设置。

    无法提交断点LineBreakpoint hibernate4CURD : -1, 原因是: 找不到 URL 'file:/E:/版本控制/Design-java/hibernate4CURD/' 的 ...

  6. 20.DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    一 认证组件 1. 局部认证组件 我们知道,我们不管路由怎么写的,对应的视图类怎么写的,都会走到dispatch方法,进行分发, 在咱们看的APIView类中的dispatch方法的源码中,有个sel ...

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

    1 数据解析器 1 什么是解析器 相当于request 中content-type 对方传什么类型的数据,我接受什么样的数据:怎样解析 无论前面传的是什么数据,都可以解开 例如:django不能解析j ...

  8. 动态多条件查询分页以及排序(一)--MVC与Entity Framework版url分页版

    一.前言 多条件查询分页以及排序  每个系统里都会有这个的代码 做好这块 可以大大提高开发效率  所以博主分享下自己的6个版本的 多条件查询分页以及排序 二.目前状况 不论是ado.net 还是EF ...

  9. EasyUI DataGrid 使用(分页,url数据获取,data转json)

    EasyUI算是比较有名的,搜一下网上的资料也比较多,具体的参数,下载地址我就不写了 平常也不怎么写文章,大部分都是代码,有不能运行的可以直接评论回复 有可能遇到的问题: json数据格式,这个要仔细 ...

随机推荐

  1. Flutter Widgets 之 BottomNavigationBar 和 BottomNavigationBarItem

    注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 BottomNavigationBar 和 BottomN ...

  2. [红日安全]Web安全Day4 - SSRF实战攻防

    本文由红日安全成员: MisakiKata 编写,如有不当,还望斧正. 大家好,我们是红日安全-Web安全攻防小组.此项目是关于Web安全的系列文章分享,还包含一个HTB靶场供大家练习,我们给这个项目 ...

  3. win10环境下VS2019配置NTL库

    win10环境下VS2019配置NTL库 1.下载 WINNTL库文件     https://www.shoup.net/ntl/download.html 2.创建静态库 文件->新建-&g ...

  4. 压力测试(四)-Mysql数据库压测实操

    1.Jmeter压测实战之JDBC request压测Mysql讲解 简介:讲解jdbc压测mysql相关准备工作,jar包添加,配置讲解 1.Thread Group -> add -> ...

  5. 关于localStorage面试的那点事

    最近面试的时候关于html5API总会被问到localStorage的问题, 对于一般的问题很简单,无非就是 localStorage.sessionStorage和cookie这三个客户端缓存的区别 ...

  6. frp 内网穿透访问内网Web服务

    ps:最近想要通过域名(公网)访问或者测试在本地搭建的 web 服务(不想在公网IP服务器上再部署个服务,也不想通过teamview等工具远程卡到爆!), 由于本地机器没有公网 IP,无法将域名解析到 ...

  7. 基于springcloud搭建项目-Hystrix篇(五)

    1.概述 (1).首先要知道分布式系统面临的问题复杂分布式体系结构中应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免的失败 (2).服务雪崩 多个服务之间相互调用的时候,假设微服务A调用微服 ...

  8. seo搜索优化教程11-seo搜索优化关键词策略

    为了使大家更方便的了解及学习网络营销推广.seo搜索优化,星辉科技强势推出seo搜索优化教程.此为seo教程第11课 关键词在seo搜索优化中有着重要的地位,本节主要讲解seo搜索优化中关键词优化的相 ...

  9. django 引入静态文件(前端样式等)

    1.首先在主项目目录下settings.py文件中添加如下代码 2.然后在主项目目录,app项目同级目录下新建static文件夹并在文件夹中新建css文件夹,用于存放css文件,如下: 3.前端渲染时 ...

  10. nes 红白机模拟器 第2篇 InfoNES

    InfoNES 支持 map ,声音,代码比较少,方便 移值. 在上个 LiteNES  的基础上,其实不到半小时就移值好了这个,但问题是,一直是黑屏.InfoNES_LoadFrame ()  Wo ...