之前已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful-API的一个理念,每一个URL代表着一个资源。当然RESTful API的另一个特性就是,发送不同的请求动作,会返还不同的响应。
Request对象
平时我们在写Django的视图函数的时候,都会带上一个request参数,这样就能处理平时搭建网站时,浏览器访问网页时发出的常规的HttpRequest。但是现在我们导入了django-rest-framework,它能够对request进行拓展,并且提供更灵活的请求解析。这个特性体现在哪呢?请看下面这个例子:
request.POST # 只能处理表单数据.只能处理POST请求 |
这个例子里面的注释已经说得很清楚,拓展后的request使用request.data就可以处理各种各样的请求了,而原本的request在处理时需要指定请求模式。
Response对象
和request对象一样,django-rest-framewor也对其进行了很实用的拓展,在我上一篇文章的snippets/views.py中,我们导入了JsonResponse用于返回json格式的响应,在视图函数中是这样的:
|
也就是说,在return的时候就需要指明json格式,这样显得很不实用而且很单一,所以经过拓展后的Reponse对象就很方便了,它会根据客户端的请求头部信息来确定正确的内容类型以返回给客户端。只需如下代码:
return Response(data) |
状态码
我们知道发送http请求时会返回各种各样的状态吗,但是都是简单的数字,比如200、404等,这些纯数字标识符有时候可能不够明确或者客户端在使用的时候不清楚错误信息甚至是没注意看不到,所以django-rest-framework也对此进行了优化,状态码会是HTTP_400_BAD_REQUEST、HTTP_404_NOT_FOUND这种,极大的提高可读性。
装饰API视图
REST框架还提供了一个装饰器和一个类来包装视图函数,可以使用它们来写API视图,让程序能处理的情况更多。
- @api_view装饰器用在基于视图的方法上。
- APIView类用在基于视图的类上。
注意:
这里使用的是基于视图方法,所以使用的是装饰器@api_view,APIview这个类暂时不会提及。
这两个东西提供的一些功能,让我们省去很多工作,比如说确保你在视图中收到Request对象或在你的Response对象中添加上下文,这样就能实现内容通信。
另外装饰器可以在接收到输入错误的request.data时抛出ParseError异常,或者在适当的时候返回405 Method Not Allowed状态码。
改进代码
上面说了这么多拓展和优化,接下来就把它们都使用起来,改进一下原本的snippets/views.py,程序如下:
from rest_framework import status # 导入HHTP状态 |
可以看出,经过改进的代码已经把上面所说的几个django-rest-framework带来的特性都应用起来了,我们可以看出程序代码量变少,并且能处理的情况更多了。 比如说,在原本的视图函数snippet_detail中,处理'PUT'请求的时候,需要先解析json格式的数据再进一步处理:
data = JSONParser().parse(request) |
也就是说需要分成两步实现,而且这里有一个限制就是只能解析json格式的数据流。而改进后的程序只需一行代码:
serializer = SnippetSerializer(data=request.data) |
直接使用之前说的request.data就可以获取到提交过来的数据了,并且可以处理各种数据和各种请求动作,方便了开发。
还有在return的时候也不需要指定json格式了,由原本的
return JsonResponse(serializer.data, status=201) |
改成了
return Response(serializer.data,status=status.HTTP_201_CREATED) |
这也意味着返回给客户端的可以是json或者html等格式的内容,返回HTML格式的内容的话,会在浏览器返回经过渲染的、更美观的页面。同时可以看出状态码也改进成了django-rest-framework给我们带来的可读性更高的状态标识码,以上这些措施都很大程度的提高了对客户的友好度。
对于另一个视图函数的修改也是同样的原理,这里就不做同样的讲解了,代码如下:
|
以上就是对原有的常规的Django视图函数的改进。
总结一下:
处理request提交过来的数据不需要一定是
json格式的数据,返回的响应也不需要一定是json数据,也可以是经过渲染的HTML页面。稍后就会示范使用。
URL添加格式后缀
既然上面已经说了返回给客户端的Response可是json或者是HTML等格式的内容,那么用户在使用的时候是如何指定返回哪种格式的内容呢,那就是在URL的最后加上后缀。
比如http://127.0.0.1:8000/snippets.json,这样就是用户自己指定了返回json格式的Response,而不是我们在后台指定返回固定的格式。
只需对我们的程序稍加改进就可以了,在两个视图函数添加关键词参数format:
def snippet_list(request, format=None): |
以及
def snippet_detail(request, pk, format=None): |
再修改一下snippets/urls.py,导入format_suffix_patterns(格式后缀模式):
from django.conf.urls import url |
测试Api
首先当然还是可以像上一篇文章中那样的使用:
http http://127.0.0.1:8000/snippets/ |

- 通过设置Accept头部信息来控制返回的格式
http http://127.0.0.1:8000/snippets/ Accept:application/json # JSON |
效果如下(返回的是页面的HTML代码,只展示了一部分):

- 直接加格式后缀
http http://127.0.0.1:8000/snippets.json # JSON suffix |
- 浏览器查看Api
我们可以直接在浏览器输入 http://127.0.0.1:8000/snippets.api 进行查看,会得到一个美观的页面:
实现功能
增加数据
我们可以控制 Content-Type 头部信息来提交POST请求:
http --form POST http://127.0.0.1:8000/snippets/ code="print 123" |
它会自动在原有的数据后面添加你提交过去的数据,效果如下:

修改数据
我们通过PUT来实现修改功能,在我们之前定义的函数views.snippet_detail中:
url(r'^snippets/(?P<pk>[0-9]+)$', views.snippet_detail), |
所以通过 url snippets/[id]就可以访问到我们要的数据,就可以对其进行修改。
http --json PUT http://127.0.0.1:8000/snippets/1.json code="sss" |

删除数据
同之前的修改一样,我们使用DELETE,通过 url snippets/[id]访问数据,提交删除。
http DELETE http://127.0.0.1:8000/snippets/8.json |
这样我们就成功的删除了一条数据。
声明
本篇文章来自ziv的博客,仅作整理学习分享。
点击这里访问原文