API(二)之Requests and Responses
这一部分可以让返回的api信息以两种格式呈现:.json和.api
REST框架的核心部分。我们来介绍几个基本的组成部分。
Request objects
REST框架引入了Request
对象来扩展常规的HttpRequest
,并提供更灵活的请求解析。Request
对象的核心功能是request.data
属性,它与request.POST
相似,但对web API更有用。
request.POST # Only handles form data. Only works for 'POST' method.
request.data # Handles arbitrary data. Works for 'POST', 'PUT' and 'PATCH' methods.
Response objects
REST框架还引入了Response
对象,which is a type of TemplateResponse
that takes unrendered content and uses content negotiation to determine the correct content type to return to the client.
return Response(data) # Renders to content type as requested by the client.
Status codes
在您的视图中使用数字HTTP状态码并不总是利于阅读,如果您收到 an error code wrong你将很难注意到。 REST框架为每一个状态码更明确的标识符,如status
模块中的HTTP_400_BAD_REQUEST。
使用这些标识符比使用数字标识符要好的多。
HTTP_100_CONTINUE = 100
HTTP_101_SWITCHING_PROTOCOLS = 101
HTTP_200_OK = 200
HTTP_201_CREATED = 201
HTTP_202_ACCEPTED = 202
HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
HTTP_204_NO_CONTENT = 204
HTTP_205_RESET_CONTENT = 205
HTTP_206_PARTIAL_CONTENT = 206
HTTP_207_MULTI_STATUS = 207
HTTP_300_MULTIPLE_CHOICES = 300
HTTP_301_MOVED_PERMANENTLY = 301
HTTP_302_FOUND = 302
HTTP_303_SEE_OTHER = 303
HTTP_304_NOT_MODIFIED = 304
HTTP_305_USE_PROXY = 305
HTTP_306_RESERVED = 306
HTTP_307_TEMPORARY_REDIRECT = 307
HTTP_400_BAD_REQUEST = 400
HTTP_401_UNAUTHORIZED = 401
HTTP_402_PAYMENT_REQUIRED = 402
HTTP_403_FORBIDDEN = 403
HTTP_404_NOT_FOUND = 404
HTTP_405_METHOD_NOT_ALLOWED = 405
HTTP_406_NOT_ACCEPTABLE = 406
HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
HTTP_408_REQUEST_TIMEOUT = 408
HTTP_409_CONFLICT = 409
HTTP_410_GONE = 410
HTTP_411_LENGTH_REQUIRED = 411
HTTP_412_PRECONDITION_FAILED = 412
HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413
HTTP_414_REQUEST_URI_TOO_LONG = 414
HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416
HTTP_417_EXPECTATION_FAILED = 417
HTTP_422_UNPROCESSABLE_ENTITY = 422
HTTP_423_LOCKED = 423
HTTP_424_FAILED_DEPENDENCY = 424
HTTP_428_PRECONDITION_REQUIRED = 428
HTTP_429_TOO_MANY_REQUESTS = 429
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451
HTTP_500_INTERNAL_SERVER_ERROR = 500
HTTP_501_NOT_IMPLEMENTED = 501
HTTP_502_BAD_GATEWAY = 502
HTTP_503_SERVICE_UNAVAILABLE = 503
HTTP_504_GATEWAY_TIMEOUT = 504
HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505
HTTP_507_INSUFFICIENT_STORAGE = 507
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511
Wrapping API views
REST框架提供了两个可用于编写API视图的wrappers。
- 适用于function-based views的
@api_view
。 - 适用于class-based views的
APIView
。
这些wrappers提供了一些功能,例如确保您在视图中接收Request
实例,并将上下文添加到Response
对象,以便可以执行content negotiation。
The wrappers also provide behaviour such as returning 405 Method Not Allowed
responses when appropriate, and handling any ParseError
exception that occurs when accessing request.data
with malformed input.
Pulling it all together
好的,我们开始使用这些新的组件来写几个视图。
views.py
中不再需要JSONResponse
class, 所以请删除它。一旦完成这些,我们就可以开始重构我们视图了.
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer @api_view(['GET', 'POST'])
def snippet_list(request):
"""
List all snippets, or create a new snippet.
"""
if request.method == 'GET':
snippets = Snippet.objects.all()
serializer = SnippetSerializer(snippets, many=True)
return Response(serializer.data) elif request.method == 'POST':
serializer = SnippetSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
我们的实例视图比以前的例子有所改进。这更加简明扼要,现在的代码与我们使用的Forms API非常相似。我们还使用命名的状态码,这使得响应意义更加明显。
以下是views.py
模块中单个的代码段视图。
@api_view(['GET', 'PUT', 'DELETE'])
def snippet_detail(request, pk):
"""
Retrieve, update or delete a snippet instance.
"""
try:
snippet = Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET':
serializer = SnippetSerializer(snippet)
return Response(serializer.data) elif request.method == 'PUT':
serializer = SnippetSerializer(snippet, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif request.method == 'DELETE':
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
这应该都是非常熟悉的 - 与常规的Django视图并没有什么不同。
请注意,我们不再明确地将我们的请求或响应绑定到一个给定的内容类型。request.data
能够处理输入的 json
requests,但它也可以处理其他格式。同样,we're returning response objects with data,但允许REST框架将响应渲染成正确的内容类型。
给url添加可选的格式后缀
我们的响应不再与单一内容类型连接,为了充分利用这个事实,我们可以为API端点添加一些格式后缀。使用格式后缀给urls明确指定一个格式,这意味着我们的API将能处理诸如http://example.com/api/items/4.json之类的urls。
首先给两个视图添加关键字参数format
,就像这样。
def snippet_list(request, format=None):
and
def snippet_detail(request, pk, format=None):
然后更新urls.py
文件,给已经存在的urls附加一组format_suffix_patterns。
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views urlpatterns = [
url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P<pk>[0-9]+)$', views.snippet_detail),
] urlpatterns = format_suffix_patterns(urlpatterns)
我们不是一定要添加这些额外的url模式,但它给了我们一个简单、干净的方式来引用特定的格式。
How's it looking?
在命令行中测试API,就像我们在第1部分中所做的那样。一切工作都非常相似,尽管如果发送无效请求,我们已经有了更好的错误处理。
我们可以像以前一样获取所有片段的列表。
http http://127.0.0.1:8000/snippets/ HTTP/1.1 200 OK
...
[
{
"id": 1,
"title": "",
"code": "foo = \"bar\"\n",
"linenos": false,
"language": "python",
"style": "friendly"
},
{
"id": 2,
"title": "",
"code": "print \"hello, world\"\n",
"linenos": false,
"language": "python",
"style": "friendly"
}
]
我们可以通过使用Accept header
来控制响应的格式:
http http://127.0.0.1:8000/snippets/ Accept:application/json # Request JSON
http http://127.0.0.1:8000/snippets/ Accept:text/html # Request HTML
或者通过附加格式后缀:
http http://127.0.0.1:8000/snippets.json # JSON suffix
http http://127.0.0.1:8000/snippets.api # Browsable API suffix
类似地,我们可以使用Content-Type header
来控制我们发送的请求的格式。
# POST using form data
http --form POST http://127.0.0.1:8000/snippets/ code="print 123" {
"id": 3,
"title": "",
"code": "print 123",
"linenos": false,
"language": "python",
"style": "friendly"
} # POST using JSON
http --json POST http://127.0.0.1:8000/snippets/ code="print 456" {
"id": 4,
"title": "",
"code": "print 456",
"linenos": false,
"language": "python",
"style": "friendly"
}
如果您向上述的http requests添加--debug
,你将可以在请求头中查看请求类型。
现在,在Web浏览器中打开API,访问http://127.0.0.1:8000/snippets/。
API(二)之Requests and Responses的更多相关文章
- Tutorial 2: Requests and Responses
转载自:http://www.django-rest-framework.org/tutorial/2-requests-and-responses/ Tutorial 2: Requests and ...
- 02_Tutorial 2: Requests and Responses 请求和响应
1.请求和响应 1.文档 https://www.django-rest-framework.org/tutorial/2-requests-and-responses/ https://q1mi.g ...
- Civil 3D API二次开发学习指南
Civil 3D构建于AutoCAD 和 Map 3D之上,在学习Civil 3D API二次开发之前,您至少需要了解AutoCAD API的二次开发,你可以参考AutoCAD .NET API二次开 ...
- 用JSON-server模拟REST API(二) 动态数据
用JSON-server模拟REST API(二) 动态数据 上一篇演示了如何安装并运行 json server , 在这里将使用第三方库让模拟的数据更加丰满和实用. 目录: 使用动态数据 为什么选择 ...
- Express4.x API (二):Request (译)
写在前面 最近学习express想要系统的过一遍API,www.expressjs.com是express英文官网(进入www.epxressjs.com.cn发现也是只有前几句话是中文呀~~),所以 ...
- Linux -- 基于zookeeper的java api(二)
Linux -- 基于zookeeper的java api(二) 写一个关于基于集群的zookeeper的自定义实现HA 基于客户端和监控器:使用监控的方法查看每个注册过的节点的状态来做出操作. Wa ...
- django rest_framework入门三-Requests和Responses
这一节,我们介绍rest_framework的Requests和Responses对象,来替代django.http的HttpRequest和HttpResponse对象 1.Requests和Res ...
- 百度地图API二:根据标注点坐标范围计算显示缩放级别zoom自适应显示地图
原文:百度地图API二:根据标注点坐标范围计算显示缩放级别zoom自适应显示地图 版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/liusaint1992/ ...
- 爬虫学习(二)requests模块的使用
一.requests的概述 requests模块是用于发送网络请求,返回响应数据.底层实现是urllib,而且简单易用,在python2.python3中通用,能够自动帮助我们解压(gzip压缩的等) ...
- Day029 JDK8中新日期和时间API (二)
# JDK8中新日期和时间API (二) Instant介绍 Instant:时间线上的一个瞬时点. 这可能被用来记录应用程序中的事件时间 戳. 在处理时间和日期的时候,我们通常会想到年,月,日,时, ...
随机推荐
- springboot mybatis pagehelper 分页问题
1:添加依赖 compile group: 'com.github.pagehelper', name: 'pagehelper-spring-boot-starter', version: '1.2 ...
- version-script 控制 so的符号输出
http://blog.sina.com.cn/s/blog_493667730100csde.html https://stackoverflow.com/questions/8129782/ver ...
- 为Docker容器设置http代理
以下内容复制自:传送门 ,可以直接去该地址查看. HTTP/HTTPS proxy The Docker daemon uses the HTTP_PROXY, HTTPS_PROXY, and NO ...
- OpenWrt 18.06.1的ss-redir, 以及在乐视超4 X40上看Youtube
在18.06里面要设个透明代理, 就一直不成功 各种TIME OUT, PRIVATE SSL ERROR, 换回旧版的luci-app-shadowsocks也不行. 我就一直想, 到底这东西还能有 ...
- android的activity被杀死后如何重启
最近公司的大屏展示机器人上的程序运行时间长了,比如五天,十天会出现偶尔的崩溃,查日志可能是内存溢出或者是ndk层的错误,这种错误一时也不太好查找,但是产品那边有个要求就是程序退出了一定要能重启,能抓日 ...
- JS前台效果
最新的在上面 2014年3月3日14:46:46 百分比思路 function fixWidth(percent) { return document.body.clientWidth * perce ...
- WRI$_ADV_OBJECTS表过大,导致PDB的SYSAUX表空间不足
现象监控发现sysaux表空间使用不断增加,导致表空间不足 查看过程 查看版本: SQL> select * from v$version; BANNER CON_ID ------------ ...
- Appium 输入 & 符号,实际输入&-
2018-10-11 12:27:12:178 - [debug] [MJSONWP] Calling AppiumDriver.setValue() with args: [["& ...
- (Java编程思想)Thinking in Java
1. 为什么突然想去研读<Thinking in Java>? 最近终于下定决心撸了一本<Thinking in Java>第四版,虽然在此之前我就久闻这本书的大名,但一直未曾 ...
- openfire开发文档
http://www.blogjava.net/yi88han/archive/2009/02/11/254203.html