Django-restframework之路由控制、解析器及响应器
django-restframework之路由控制、解析器及响应器
一 前言
本篇博客介绍 restframework 框架的剩下几个组件,路由控制有三种:传统路由、半自动路由及全自动路由;解析器是用来解析要响应的数据格式,比如是form-data
、json
、或是urlencoded
等数据格式;响应器根据用户请求 url 或用户可以接受的数据格式来筛选出合适的渲染组件。
二 路由控制
一 传统路由
urls.py
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()),
]
views.py
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("")
二 半自动路由(视图类继承 ModelViewSet)
原理就是重写 as_view方法,以致可以找到请求方法和响应视图方法的对应关系。
urls.py
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'})),
]
views.py
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
三 全自动路由(自动生成路由)
urls.py
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))
]
views.py
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
三 解析器
一 解析器的作用
根据请求头的Content-Type
参数来选择对应的解析器对请求体内容进行处理,有application/json
、x-www-form-urlencoded
、form-data
等格式。
二 全局使用解析器
settings.py
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser'
'rest_framework.parsers.FormParser'
'rest_framework.parsers.MultiPartParser'
]
}
urls.py
urlpatterns = [
url(r'test/', TestView.as_view()),
]
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
class TestView(APIView):
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
三 局部使用解析器
- 仅处理请求头 content-type 为 application/json 的请求体
urls.py
from django.conf.urls import url, include
from web.views.s5_parser import TestView
urlpatterns = [
url(r'test/', TestView.as_view(), name='test'),
]
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser
class TestView(APIView):
# 局部配置该参数
parser_classes = [JSONParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
- 仅处理请求头 content-type 为 application/x-www-form-urlencoded 的请求体
urls.py
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r'test/', TestView.as_view(), name='test'),
]
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import FormParser
class TestView(APIView):
parser_classes = [FormParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
- 仅处理请求头 content-type 为 multipart/form-data 的请求体
urls.py
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r'test/', TestView.as_view(), name='test'),
]
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import MultiPartParser
class TestView(APIView):
parser_classes = [MultiPartParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/" method="post" enctype="multipart/form-data">
<input type="text" name="user" />
<input type="file" name="img">
<input type="submit" value="提交">
</form>
</body>
</html>
- 仅上传文件
urls.py
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r'test/(?P<filename>[^/]+)', TestView.as_view(), name='test'),
]
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import FileUploadParser
class TestView(APIView):
parser_classes = [FileUploadParser, ]
def post(self, request, filename, *args, **kwargs):
print(filename)
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data">
<input type="text" name="user" />
<input type="file" name="img">
<input type="submit" value="提交">
</form>
</body>
</html>
- 同时多个 parser
当同时使用多个 parser 时,restframework 会根据请求头 content-ty 自动进行对应,并使用相应的 parset
urls.py
from django.conf.urls import url, include
from web.views import TestView
urlpatterns = [
url(r'test/', TestView.as_view(), name='test'),
]
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
class TestView(APIView):
parser_classes = [JSONParser, FormParser, MultiPartParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
四 解析器源码分析
当调用request.data
时才进行解析数据,这里的 request 是Request
类对象。
1. request.data
2. request._load_data_and_files
3. request._parse
4. request._stream
5. self.parsers
6. self.parser_classes
self.parser_classes就是设置在视图类中的一个列表
7. self.negotiator.select_parser
根据数据格式选择对应的数据解析器
8. self.get_parser_context
9. stream、media_type和 self.parser_context准备好
10. 假设该解析器为 JSONParser
四 响应器
一 作用
根据用户请求的 URL 或用户可接受的数据类型,筛选出合适的渲染组件。
用户请求 URL:
二内置渲染器
显示 json 格式:JSONRenderer
访问 url:
默认显示格式:BrowsableAPIRenderer(可以修改 html 文件)
访问 url:
表格方式: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:
三 局部使用
from rest_framework.renderers import HTMLFormRenderer,BrowsableAPIRenderer
class BookDetailView(APIView):
renderer_classes = [HTMLFormRenderer,BrowsableAPIRenderer ]
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("")
四 全局使用
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES':['rest_framework.renderers.JSONRenderer']
}
五 自定义显示模板
views.py
from rest_framework.renderers import TemplateHTMLRenderer
class BookDetailView(APIView):
renderer_classes = [TemplateHTMLRenderer]
def get(self,request,pk):
book_obj=models.Book.objects.filter(pk=pk).first()
bs=BookSerializers(book_obj,many=False)
return Response(bs.data,template_name='aa.html')
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ title }}
{{ publishDate }}
</body>
</html>
Django-restframework之路由控制、解析器及响应器的更多相关文章
- Django框架深入了解_04(DRF之url控制、解析器、响应器、版本控制、分页)
一.url控制 基本路由写法:最常用 from django.conf.urls import url from django.contrib import admin from app01 impo ...
- Django drf:视图层封装、ViewSetMixin、路由配置、解析器、响应器
一.视图层封装 二.ViewSetMixin 三.路由配置 四.解析器 五.响应器 一.视图层封装 1.基本视图 写一个出版社的增删改查resfull接口 路由: url(r'^publish/$', ...
- DRF url控制 解析器 响应器 版本控制 分页(常规分页,偏移分页,cursor游标分页)
url控制 第二种写法(只要继承了ViewSetMixin) url(r'^pub/$',views.Pub.as_view({'get':'list','post':'create'})), #获取 ...
- Django Rest Framework(版本、解析器、序列化、数据验证)
一.版本 程序也来越大时,可能通过版本不同做不同的处理 没用rest_framework之前,我们可以通过以下这样的方式去获取. class UserView(APIView): def get(se ...
- Django REST framework基础:解析器和渲染器
解析器 解析器的作用 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 在了解解析器之前,我们要先知道Accept以及ContentTy ...
- Django Rest framework 框架之解析器
解析器 序列化***** 请求数据进行校验 对queryset进行序列化处理 分页 路由 视图 渲染器
- 六、django rest_framework源码之解析器剖析
1 绪论 网络传输数据只能传输字符串格式的,如果是列表.字典等数据类型,需要转换之后才能使用但是我们之前的rest_framework例子都没有转换就直接可以使用了,这是因为rest_framewor ...
- 「Django」rest_framework学习系列-解析器
满足两个要求,request.Post中才有值 1.请求头要求:请求头中的Content-Type为application/x-www-form-urlencoded 2.数据格式要求 name=x& ...
- Django day28 频率组件,解析器
一:频率组件: 1.频率是什么? 节流,访问控制 2. (1)内置的访问频率控制类SimpleRateThrottle (2)写一个类,继承SimpleRateThrottle class MyThr ...
随机推荐
- 虚拟机console基础环境配置——安装VMware Tools
1. 虚拟机设置中点击安装2. 虚拟机中挂载VMware Tools镜像3. 解压安装4. 配置共享目录5. 有关VMware Tools 1. 虚拟机设置中点击安装 VMware workstati ...
- java JDK配置环境变量
1)将下载的jdk放置到一定文件夹中,注意文件夹名不能有中文! 2)设置环境变量 a.可以在系统变量中找到path这个变量,然后将jdk下的bin的根目录添加进去 注意:一定要放在path变量值的最前 ...
- 实验吧 ---- 隐写术之so beautiful so white
因为好久没有写博客,所以今天本宝宝要弥补这个过错,一下子更新许多文章,希望各位小伙伴能够原谅,以后我会加倍努力的! 这一次主要都是实验吧里面的 关于隐写术方面的知识,后续我会上传一些解密工具,希望能够 ...
- h5仿微信聊天(高仿版)、微信聊天表情|对话框|编辑器
之前做过一版h5微信聊天移动端,这段时间闲来无事就整理了下之前项目,又重新在原先的那版基础上升级了下,如是就有了现在的h5仿微信聊天高仿版,新增了微聊.通讯录.探索.我四个模块 左右触摸滑屏切换,聊天 ...
- 最新.net和Java调用SAP RFC中间件下载
还记得2012年初我发布的全网络第一个关于.net 连接SAP RFC的NCO3原创博文,用的就是SAP出的最新的.Net Connector 3.0的版本,在那个时候都是普遍用其他蹩脚的方式或Web ...
- 浅谈surging服务引擎中的rabbitmq组件和容器化部署
1.前言 上个星期完成了surging 的0.9.0.1 更新工作,此版本通过nuget下载引擎组件,下载后,无需通过代码build集成,引擎会通过Sidecar模式自动扫描装配异构组件来构建服务引擎 ...
- 二维码神器QRCoder
好久没有写Blog,都是因为不小心坠入了爱河,时间都给我家那位了,都没时间加班了(嗨呀,不小心撒了一下狗粮),不过,还是希望单身的赶紧找到心仪的另一半,实在找不到,那就加班啊(开个玩笑,别认真). 二 ...
- pods "xxx" is forbidden: SecurityContext.RunAsUser is forbidden
报错信息如下: pods "k8s-logs-cndf5" is forbidden: SecurityContext.RunAsUser is forbidden 解决方法: 需 ...
- 面试挂在了 LRU 缓存算法设计上
好吧,有人可能觉得我标题党了,但我想告诉你们的是,前阵子面试确实挂在了 RLU 缓存算法的设计上了.当时做题的时候,自己想的太多了,感觉设计一个 LRU(Least recently used) 缓存 ...
- Sql 优化解决方案
转自:https://blog.csdn.net/jie_liang/article/details/77340905 用以记录: 在sql查询中为了提高查询效率,我们常常会采取一些措施对查询语句进行 ...