django restframwork教程之Request和Response

Request 对象

REST framework 引入了一个扩展HttpRequest的请求对象,提供了更灵活的请求解析,Request对象的核心功能是request.data属性,它类似于request.POST,但是对于Web APIs更实用

request.POST # 仅可处理表单数据,仅仅用于post请求.request.data # 处理任意数据, 可供 'POST', 'PUT' and 'PATCH' 请求使用.

Response对象

REST framework 也引入了一个response对象,它是一种TemplateResponse类型,它渲染文本内容,并根据内容决定返回给客户端的数据类型

return Response(data) # 通过客户端请求返回渲染的内容

Status Code 状态码

在你的视图中使用数字http 状态码不利于阅读,它很容易让你不会注意到代码的错误,REST framework为每个状态码提供了更加明确的标示,例如HTTP_400_BAD_REQUEST在status模块中,使用这个来代替数字是一个不错的方法

封装API视图

REST framework提供了两种封装器,你可以使用他们写views

  • @api_view 装饰器用在函数的view中
  • @APIView 装饰器用在类的view中

这两个装饰器提供了一些功能。例如确保在你的view中收到request请求和在response对象中添加context从而能够根据内容协商渲染

装饰器还提供了一些行为,如适当的返回405 Method Not Allowed不允许请求的响应,以及当访问request.data发生格式错误时处理任何ParseError异常

开始组装使用

接上一篇的代码,现在我们的view视图中不再需要JSONResponse 类,所以先删除它,然后开始重构我们的视图

from rest_framework import statusfrom rest_framework.decorators import api_viewfrom rest_framework.response import Responsefrom snippets.models import Snippetfrom 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)@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请求,但是它也能处理其他格式。相似地,虽然我们可以在响应对象中带数据,但允许REST框架渲染响应成正确的内容类型。

在我们的UIRLs中添加可选的格式后缀

为了突出我们的response不再是单一的格式内容的事实,让我们在API URL尾部添加格式后缀,用格式后缀给我们明确参考指定格式的URL,类似于http://example.com/api/items/4.json.

增加format关键字参数在views中

def snippet_list(request,format=None)def snippet_detail(request, pk,format=None):

接着更新我们的urls.py文件,添加一个format_suffix_patterns的参数

from django.conf.urls import urlfrom snippets import viewsfrom rest_framework.urlpatterns import format_suffix_patternsurlpatterns = [ url(r'^snippets/$', views.snippet_list), url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail),]urlpatterns = format_suffix_patterns(urlpatterns)

我们不一定需要添加这些额外的url模式,但它给了我们一个简单,干净的方式来引用一个特定的格式。

看看效果

我们要开始从命令行测试API。虽然我们能在发送无效的请求时更妥当处理错误,但是现在一切都做的够好了。 我们能想之前一样获取所有的snippets列表

默认返回json格式curl -s http://127.0.0.1:8000/snippets/ | jq .[ { "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" }, { "id": 3, "title": "", "code": "print \"hello, world\"", "linenos": false, "language": "python", "style": "friendly" }]

指定格式访问

  • 在请求头中指定格式

curl -s http://127.0.0.1:8000/snippets/ -H "Accept:application/json" # Request JSONcurl -s http://127.0.0.1:8000/snippets/ -H "Accept:text/html" # Request HTML

  • 在url中指定格式

curl -s http://127.0.0.1:8000/snippets.json # Request JSONcurl -s http://127.0.0.1:8000/snippets.api # Request HTML

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值