- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章django rest framework之请求与响应(详解)由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言:在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源。当然我们还知道RESTful API的另一个特性就是,发送不同的请求动作,会返还不同的响应,这篇文章就讲一下django-rest-framework这个工具在这方面给我们带来的便捷操作.
1、Request对象 。
平时我们在写Django的视图函数的时候,都会带上一个request参数,这样就能处理平时搭建网站时,浏览器访问网页时发出的常规的HttpRequest。但是现在我们导入了django-rest-framework,它能够对request进行拓展,并且提供更灵活的请求解析。这个特性体现在哪呢?请看下面这个例子:
1
|
2
3
|
<
SPAN
style
=
"FONT-SIZE: 13px"
>request.POST # Only handles <
SPAN
style
=
"COLOR: #ff0000"
>form data</
SPAN
>. Only works for '<
SPAN
style
=
"COLOR: #ff0000"
>POST</
SPAN
>' method.
request.data # Handles <
SPAN
style
=
"COLOR: #ff0000"
>arbitrary(任意的) data</
SPAN
>. Works for '<
SPAN
style
=
"COLOR: #ff0000"
>POST', 'PUT' and 'PATCH</
SPAN
>' methods.
</
SPAN
>
|
request.POST只能处理前端发起的POST请求,只能处理表单提交的数据。而request.data可以处理任意数据,而不单单是前端提交的表单数据,可用于post, put, patch请求.
2、Response对象 。
和request对象一样,django-rest-framework也对其进行了很实用的拓展,在我上一篇文章的snippets/views.py中,我们导入了JsonResponse用于返回json格式的响应,在视图函数中是这样的:
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@csrf_exempt
def snippet_list(request):
"""
because we want to be able to POST to this view from clients
that won't have a CSRF token we need to mark the view as csrf_exempt
List all code snippets, or create a new snippet.
"""
if request.method == "GET":
snippets = Snippet.objects.all()
serializer = SnippetSerializer(snippets, many=True)
return JsonResponse(serializer.data, safe=False)
elif request.method == "POST":
data = JSONParser().parse(request)
serializer = SnippetSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
|
也就是说,在return的时候就需要指明json格式,这样显得很不实用而且很单一,所以经过拓展后的Reponse对象就很方便了,它会根据客户端的请求头部信息来确定正确的内容类型以返回给客户端。只需如下代码:
1
|
2
|
<
SPAN
style
=
"FONT-SIZE: 13px"
>return Response(data) # <
SPAN
style
=
"COLOR: #ff0000"
>Renders to content type as requested by the client.
</
SPAN
></
SPAN
>
|
3、状态码 。
我们知道发送http请求时会返回各种各样的状态吗,但是都是简单的数字,比如200、404等,这些纯数字标识符有时候可能不够明确或者客户端在使用的时候不清楚错误信息甚至是没注意看不到,所以django-rest-framework也对此进行了优化,状态码会是HTTP_400_BAD_REQUEST、HTTP_404_NOT_FOUND这种,极大的提高可读性 。
4、包装API视图 。
REST框架提供了两个可用于编写API视图的包装器.
•@api_view装饰器用于处理基于函数的视图 。
•APIView类用在基于视图的类上 。
这些包装提供了一些功能,让我们省去很多工作。比如说确保你在视图中收到Request对象或在你的Response对象中添加上下文,这样就能实现内容通信.
另外装饰器可以在接收到输入错误的request.data时抛出ParseError异常,或者在适当的时候返回405 Method Not Allowed状态码.
5、Pulling it all together(使用) 。
Okay, let's go ahead and start using these new components to write a few views. 。
We don't need our JSONResponse class in views.py any more, so go ahead and delete that. Once that's done we can start refactoring(重构) our views slightly. 。
在views.py文件中我们不再需要我们的JSONResponse类,所以继续删除。一旦完成,我们可以开始细微地重构我们的视图.
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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 code 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)
|
可以看出,经过改进的代码已经把上面所说的几个django-rest-framework带来的特性都应用起来了,我们可以看出程序代码量变少,并且能处理的情况更多了。 比如说,在原本的视图函数snippet_detail中,处理'PUT'请求的时候,需要先解析前端发来的json格式的数据再进一步处理:
1
|
2
3
|
<
SPAN
style
=
"FONT-SIZE: 13px"
>data = JSONParser().parse(request)
serializer = SnippetSerializer(snippet, data=data)
</
SPAN
>
|
也就是说需要分成两步实现,而且这里有一个限制就是只能解析json格式的数据流。而改进后的程序只需一行代码:
1
|
2
|
<
SPAN
style
=
"FONT-SIZE: 13px"
>serializer = SnippetSerializer(data=request.data)
</
SPAN
>
|
request.data can handle incoming json requests, but it can also handle other formats. Similarly we're returning response objects with data, but allowing REST framework to render the response into the correct content type for us. 。
request.data就可以获取到提交过来的数据了,并且可以处理各种数据和各种请求动作,方便了开发。还有在return的时候也不需要指定json格式了,由原本的:
1
|
2
|
<
SPAN
style
=
"FONT-SIZE: 13px"
>return JsonResponse(serializer.data, status=201)
</
SPAN
>
|
改成了 。
1
|
2
|
<
SPAN
style
=
"FONT-SIZE: 13px"
>return Response(serializer.data,status=status.HTTP_201_CREATED)
</
SPAN
>
|
这也意味着返回给客户端的可以是json或者html等格式的内容,返回HTML格式的内容的话,会在浏览器返回经过渲染的、更美观的页面。同时可以看出状态码也改进成了django-rest-framework给我们带来的可读性更高的状态标识码,以上这些措施都很大程度的提高了对客户的友好度.
对于另一个视图函数的修改也是同样的原理,这里就不做同样的讲解了,代码如下:
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@api_view(['GET', 'PUT', 'DELETE'])
def snippet_detail(request, pk):
"""
Retrieve, update or delete a code snippet.
"""
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提交过来的数据不需要一定是json格式的数据,返回的响应也不需要一定是json数据,也可以是经过渲染的HTML页面。稍后就会示范使用.
6、向URL添加可选的格式后缀 。
既然上面已经说了返回给客户端的Response可是json或者是HTML等格式的内容,那么用户在使用的时候是如何指定返回哪种格式的内容呢,那就是在URL的最后加上后缀。比如http://127.0.0.1:8000/snippets.json,这样就是用户自己指定了返回json格式的Response,而不是我们在后台指定返回固定的格式.
只需对我们的程序稍加改进就可以了,在两个视图函数添加关键词参数format:
1
|
|
def snippet_list(request, format=None):
|
and 。
1
|
|
def snippet_detail(request, pk, format=None):
|
Now update the urls.py file slightly, to append a set of format_suffix_patterns(格式后缀模式) in addition to the existing URLs. 。
1
|
2
3
4
5
6
7
8
9
10
|
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)
|
7、How's it looking?
Go ahead and test the API from the command line, as we did in tutorial part 1. Everything is working pretty similarly, although we've got some nicer error handling if we send invalid requests. 。
We can get a list of all of the snippets, as before. 。
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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"
}
]
|
We can control the format of the response that we get back, either by using the Accept header
1
|
2
|
<
SPAN
style
=
"FONT-SIZE: 13px"
>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</
SPAN
>
|
Or by appending a format suffix
1
|
2
|
<
SPAN
style
=
"FONT-SIZE: 13px"
>http
http://127.0.0.1:8000/snippets.json
# JSON suffix
http
http://127.0.0.1:8000/snippets.api
# Browsable API suffix</
SPAN
>
|
Similarly, we can control the format of the request that we send, using the Content-Type header. 。
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# 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"
}
|
If you add a --debug switch to the http requests above, you will be able to see the request type in request headers. 。
Now go and open the API in a web browser, by visiting http://127.0.0.1:8000/snippets/. 。
Browsability 。
Because the API chooses the content type of the response based on the client request, it will, by default, return an HTML-formatted representation of the resource when that resource is requested by a web browser. This allows for the API to return a fully web-browsable HTML representation. 。
Having a web-browsable API is a huge usability win, and makes developing and using your API much easier. It also dramatically lowers the barrier-to-entry for other developers wanting to inspect and work with your API. 。
See the browsable api topic for more information about the browsable API feature and how to customize it. 。
浏览功能(中文) 。
由于API根据客户端请求选择响应的内容类型,因此默认情况下,当Web浏览器请求资源时,将返回HTML格式的资源表示形式。这允许API返回完全的可浏览网页的HTML表示.
拥有一个可浏览网页的API是一个巨大的可用性胜利,并且使开发和使用您的API更容易。它也大大降低了想要检查和使用您的API的其他开发人员的入门障碍.
有关可浏览的API功能以及如何对其进行定制的更多信息,请参阅可浏览的api主题.
以上这篇django rest framework之请求与响应(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我.
原文链接:http://www.cnblogs.com/0zcl/p/7787354.html 。
最后此篇关于django rest framework之请求与响应(详解)的文章就讲到这里了,如果你想了解更多关于django rest framework之请求与响应(详解)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试从该网站抓取历史天气数据: http://www.hko.gov.hk/cis/dailyExtract_uc.htm?y=2016&m=1 在阅读了 AJAX 调用后,我发现请求数据的正确
我有两个 postman 请求 x,y,它们命中了两个不同的休息 api X,Y 中的端点。 x 会给我一个身份验证 token ,这是发出 y 请求所必需的。如何在请求 y 中发出请求 x ?也就是
我使用请求库通过 API 与其他服务器进行通信。但现在我需要同时发送多个(10 个或更多)POST 请求,并且只有在所有响应都正确的情况下才能进一步前进。通常语法看起来有点像这样: var optio
背景:当用户单击按钮时,其类会在class1和class2之间切换,并且此数据是通过 AJAX 提交。为了确认此数据已保存,服务器使用 js 进行响应(更新按钮 HTML)。 问题:如果用户点击按钮的
我正在将 Node.js 中的请求库用于 Google 的文本转语音 API。我想打印出正在发送的请求,如 python example . 这是我的代码: const request = requi
我经常使用requests。最近我发现还有一个 requests2 和即将到来的 requests3 虽然有一个 page其中简要提到了 requests3 中的内容,我一直无法确定 requests
我正在尝试将图像发送到我的 API,然后从中获取结果。例如,我使用发送一个 bmp 图像文件 file = {"img": open("img.bmp)} r = requests.post(url,
我发现 Google Cloud 确保移出其物理环境的任何请求都经过强制加密,请参阅(虚拟机到虚拟机标题下的第 6 页)this link Azure(和 AWS)是否遵循类似的程序?如果有人能给我指
我有一个 ASP.NET MVC 应用程序,我正在尝试在 javascript 函数中使用 jQuery 来创建一系列操作。该函数由三部分组成。 我想做的是:如果满足某些条件,那么我想执行同步 jQu
我找不到如何执行 get http 请求,所以我希望你们能帮助我。 这个想法是从外部url(例如 https://api.twitter.com/1.1/search/tweets.json?q=tw
我的应用只需要使用“READ_SMS”权限。我的问题是,在 Android 6.0 上,当我需要使用新的权限系统时,它会要求用户“发送和查看短信”。 这是我的代码: ActivityCompat.re
我的前端代码: { this.searchInput = input; }}/> 搜索 // search method: const baseUrl = 'http://localho
我有一个由 AJAX 和 C# 应用程序使用的 WCF 服务, 我需要通过 HTTP 请求 header 发送一个参数。 在我的 AJAX 上,我添加了以下内容并且它有效: $.ajax({
我正在尝试了解如何使用 promises 编写代码。请检查我的代码。这样对吗? Node.js + 请求: request(url, function (error, response, body)
如果失败(除 HTTP 200 之外的任何响应代码),我需要重试发送 GWT RPC 请求。原因很复杂,所以我不会详细说明。到目前为止,我在同一个地方处理所有请求响应,如下所示: // We
当用户单击提交按钮时,我希望提交表单。然而,就在这种情况发生之前,我希望弹出一个窗口并让他们填写一些数据。一旦他们执行此操作并关闭该子窗口,我希望发出 POST 请求。 这可能吗?如果可能的话如何?我
像 Facebook 这样的网站使用“延迟”加载 js。当你必须考虑到我有一台服务器,流量很大时。 我很感兴趣 - 哪一个更好? 当我一次执行更多 HTTP 请求时 - 页面加载速度较慢(由于限制(一
Servlet 容器是否创建 ServletRequest 和 Response 对象或 Http 对象?如果是ServletRequest,谁在调用服务方法之前将其转换为HttpServletReq
这是维基百科文章的摘录: In contrast to the GET request method where only a URL and headers are sent to the serv
我有一个循环,每次循环时都会发出 HTTP post 请求。 for(let i = 1; i console.log("succes at " + i), error => con
我是一名优秀的程序员,十分优秀!