请求和响应

请求对象(Request objects)

REST框架引入了一个扩展了常规HttpRequestRequest对象,并提供了更灵活的请求解析。Request对象的核心功能是request.data属性,它与request.POST类似,但对于使用Web API更为有用。

request.POST  # 只处理表单数据  只适用于'POST'方法
request.data  # 处理任意数据  适用于'POST''PUT''PATCH'方法

响应对象(Response objects)

REST框架还引入了一个Response对象,这是一种获取未渲染(unrendered)内容的TemplateResponse类型,并使用内容协商来确定返回给客户端的正确内容类型

return Response(data)  # 渲染成客户端请求的内容类型。

状态码(Status codes)

在你的视图(views)中使用纯数字的HTTP 状态码并不总是那么容易被理解。而且如果错误代码出错,很容易被忽略。REST框架为status模块中的每个状态代码(如HTTP_400_BAD_REQUEST)提供更明确的标识符。使用它们来代替纯数字的HTTP状态码是个很好的主意。

包装(wrapping)API视图

REST框架提供了两个可用于编写API视图的包装器(wrappers)。

  1. 用于基于函数视图的@api_view装饰器。

  2. 用于基于类视图的APIView类。

这些包装器提供了一些功能,例如确保你在视图中接收到Request实例,并将上下文添加到Response,以便可以执行内容协商。

包装器还提供了诸如在适当时候返回405 Method Not Allowed响应,并处理在使用格式错误的输入来访问request.data时发生的任何ParseError异常。

正式开始

好了,我们要创建一个用于创建简单Web API的app。

python manage.py startapp snippets

 我们需要将新建的snippetsapp和rest_frameworkapp添加到INSTALLED_APPS。让我们编辑tutorial/settings.py文件:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'quickstart.apps.QuickstartConfig',
    'snippets.apps.SnippetsConfig',
    'rest_framework',
]

请注意如果你使用的Django版本低于1.9,你需要使用snippets.apps.SnippetsConfig替换snippets

创建一个model

组合在一起

好的,我们开始使用这些新的组件来写几个视图。

我们在views.py中不再需要JSONResponse类了,所以把它删除掉。删除之后,我们就可以开始重构我们的视图了。

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)

我们的实例视图是我们之前例子的改良版。简明了很多,并且目前的代码和我们使用Forms API很相似。我们也用有意义的状态码标识符。 在views.py模块中,有一个独立的snippet视图。

复制代码
@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.data能够处理json请求,但是它也能处理其他格式。相似地,虽然我们可以在响应对象中带数据,但允许REST框架渲染响应成正确的内容类型。

在我们的链接(URLs)后添加可选格式后缀

为了利用我们的响应内容不再是单一格式的事实,我们应该为我们的API尾部添加格式后缀。用格式后缀给我们明确参考指定格式的URL,这意味着我们的API能够处理像http://example.com/api/items/4/.json一样的链接。 在视图函数中添加一个format参数,像这样:

def snippet_list(request, format=None):

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

现在可以很快更新urls.py文件,在已经存在的URL中添加一个格式后缀模式(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模式,但是它给我们简单、清楚的方式渲染除特定的格式。

看看吧

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

复制代码
http http://127.0.0.1:8000/snippets/

HTTP/1.1 200 OK
...
[
  {
    "id": 1,
    "title": "",
    "code": "foo = "bar"
",
    "linenos": false,
    "language": "python",
    "style": "friendly"
  },
  {
    "id": 2,
    "title": "",
    "code": "print "hello, world"
",
    "linenos": false,
    "language": "python",
    "style": "friendly"
  }
]
复制代码

我们能控制我们返回的响应格式,或者使用Accept响应头。

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

或者在URL后添加格式后缀:

http http://127.0.0.1:8000/snippets.json  # JSON 后缀
http http://127.0.0.1:8000/snippets.api   # 浏览用的 API 后缀

同样地,我们可以控制我们发送的请求格式,用Content-Type请求头。

复制代码
# 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"
}
复制代码

你也可以从浏览器打开API,通过访问http://127.0.0.1:8000/snippets/。

Browsability

因为API是基于客户端请求来选择响应内容的类型,所以默认情况下,在Web浏览器访问资源时,API返回HTML格式的资源。这语序API返回完全可以网页浏览的HTML。 有可以网页浏览API是很好的,这使开发和使用你的API更简单,这也为其他想要查看和使用你的API的开发者大大降低了门槛。 关于可浏览API的特性和如何自定义可浏览API,请见可浏览API话题。

接下来要干什么?

我们基于视图用类,并且看看普通的视图我们如何减少代码。


扫码关注微信公众号  “小樊Study”获取更多

 

直男们,扫我送女友哟!

原文地址:https://www.cnblogs.com/fw-qql/p/11737205.html