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 ...
随机推荐
- Java IO--字符流--InputStreamReader 和 OutputStreamWriter
今天继续学习字符流的子类!!!! 先来熟悉一下适配器设计模式:(手写的,,嘿嘿) 因为据说InputStreamReader 和OutputStreamWriter采用了适配器模式(现在我还没能理解, ...
- MySQL-5.6.36-多实例-部署(编译版)
MySQL多实例_沁贰百科 注:部署双实例前,首先需要部署单实例,单实例部署详情如下: https://www.cnblogs.com/wangqiner/p/9081002.html 1.如已经安装 ...
- Postman-----将 A 请求中 response Body 中的参数值传入到下一个请求 B 的 request body 中作为参数发送请求
问题:将A接口中response body的"id"传入到B接口的request body中. 解决办法: 1.在A接口的test中设置环境变量. 代码:var data = JS ...
- linux上MongoDB安装部署
①下载安装包 mongodb-linux-x86_64-rhel62-3.6.3.tgz ②解压: tar zxvf mongodb-linux-x86_64-rhel62-3.6.3.tgz ...
- 文本离散表示(三):TF-IDF结合n-gram进行关键词提取和文本相似度分析
这是文本离散表示的第二篇实战文章,要做的是运用TF-IDF算法结合n-gram,求几篇文档的TF-IDF矩阵,然后提取出各篇文档的关键词,并计算各篇文档之间的余弦距离,分析其相似度. TF-IDF与n ...
- 【工具篇】接口测试神器 -- Postman 入门教程
一.Postman概述 (1)工具介绍 Postman是一个接口测试工具,一款非常流行的API调试工具.在做接口测试的时候,Postman相当于一个客户端,它可以模拟用户发起的各类HTTP请求,将请求 ...
- 【重学计算机】操作系统D5章:文件系统
1. 文件系统 文件系统概述 文件的组织: 逻辑结构:流式.记录式 物理结构:顺序.连接.直接.索引 文件的存取:顺序.直接.索引 文件的控制:逻辑控制.物理控制 文件的使用:打开.关闭.读.写.控制 ...
- .NET Core IdentityServer4实战 第二章-OpenID Connect添加用户认证
内容:本文带大家使用IdentityServer4进行使用OpenID Connect添加用户认证 作者:zara(张子浩) 欢迎分享,但需在文章鲜明处留下原文地址. 在这一篇文章中我们希望使用Ope ...
- 【推荐】.NETCore 简单且高级的库 csredis v3.0.0
前言 .NETCore 从1.0发布历经坎坷,一开始各种库缺失到现在的部分完善,走到今天实属不易. 比如 redis-cli SDK 简直是坑出不穷. 过去 .net 最有名望的 ServiceSta ...
- .Net Core中利用TPL(任务并行库)构建Pipeline处理Dataflow
在学习的过程中,看一些一线的技术文档很吃力,而且考虑到国内那些技术牛人英语都不差的,要向他们看齐,所以每天下班都在疯狂地背单词,博客有些日子没有更新了,见谅见谅 什么是TPL? Task Parall ...