码迷,mamicode.com
首页 > Windows程序 > 详细

API(三)之Requests and Responses

时间:2017-05-26 13:11:08      阅读:337      评论:0      收藏:0      [点我收藏+]

标签:data   bug   res   bit   style   link   应对   nbsp   inpu   

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对象,它是TemplateResponse的一种类型,它使用未渲染的内容,并使用内容协商来确定正确的内容类型以返回给客户端。

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。 使用这些标识符比使用数字标识符要好的多。

Wrapping API views

REST框架提供了两个可用于编写API视图的wrappers。

  1. The @api_view 装饰器对function-based views有效。
  2. The APIView class对class-based views有效。

这些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,但它也可以处理其他格式。同样,我们使用数据返回响应对象,但允许REST框架将响应渲染成正确的内容类型。

Adding optional format suffixes to our URLs

我们的响应不再与单一内容类型连接,为了充分利用这个事实,我们可以为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):

Now现在稍微更新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

Similarly,类似地,我们可以使用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"
}

If you add a --debug switch to the http requests above, you will be able to see the request type in request headers.

如果您向上述的http requests添加--debug,你将可以在请求头中查看请求类型。

现在,在Web浏览器中打开API,访问http://127.0.0.1:8000/snippets/

API(三)之Requests and Responses

标签:data   bug   res   bit   style   link   应对   nbsp   inpu   

原文地址:http://www.cnblogs.com/yangxiaoling/p/6907916.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!