• 请求和响应


    请求对象(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”获取更多

     

    直男们,扫我送女友哟!

  • 相关阅读:
    C++中的命名空间
    [3D数学基础:图形与游戏开发]专栏前言
    Step01-题目申报
    《通用型云端物联网网关系统的设计与实现》
    博弈论题目总结(一)——简单组合游戏
    单纯形模板
    BZOJ 3434 [WC2014]时空穿梭 (莫比乌斯反演)
    BZOJ 3533 [SDOI2014]向量集 (线段树维护凸包)
    BZOJ 2161 布娃娃 (主席树)
    UOJ #86 mx的组合数 (数位DP+NTT+原根优化)
  • 原文地址:https://www.cnblogs.com/fw-qql/p/11737205.html
Copyright © 2020-2023  润新知