API(三)之Requests and Responses

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/

时间: 2024-10-05 09:28:28

API(三)之Requests and Responses的相关文章

Tutorial 2: Requests and Responses

转载自:http://www.django-rest-framework.org/tutorial/2-requests-and-responses/ Tutorial 2: Requests and Responses From this point we're going to really start covering the core of REST framework. Let's introduce a couple of essential building blocks. Req

02_Tutorial 2: Requests and Responses 请求和响应

1.请求和响应 1.文档 https://www.django-rest-framework.org/tutorial/2-requests-and-responses/ https://q1mi.github.io/Django-REST-framework-documentation/tutorial/2-requests-and-responses_zh/ 2.请求对象:request.data # request.data # 处理任意数据 适用于'POST','PUT'和'PATCH'

Express4.x API (三):Response (译)

Express4.x API (一):application (译) -- 进行中 Express4.x API (二):request (译) -- 完成 Express4.x API (三):Response (译) -- 完成 Express4.x API (四):router (译) -- 进行中 写在前面 技术库更迭较快,很难使译文和官方的API保持同步,更何况更多的大神看英文和中文一样的流畅,不会花时间去翻译--,所以我们看到express中文网更多的还是英文,我们只有提升自己的英语

用JSON-server模拟REST API(三) 进阶使用

前面演示了如何安装并运行 json server, 和使用第三方库真实化模拟数据 , 下面将展开更多的配置项和数据操作. 配置项 在安装好json server之后,通过 json-server -h可以看到如下配置项: json-server [options] <source> Options: --config, -c 指定 config 文件 [默认: "json-server.json"] --port, -p 设置端口号 [default: 3000] --ho

了解HTML5和“她”的 API (三)

Web Workers(后台线程) JavaScript是单线程的,较长的javascript运算会阻塞UI线程. web worker 是运行在后台的 JavaScript,不会影响页面的性能. 在web worker中执行的脚本不能访问 window对象 document对象 parent对象. web worker 一般用于更耗费 CPU 资源的任务. 检测 Web Worker 支持 //检测浏览器是否支持Web Worker if(typeof(Worker) !== "undefin

Python3网络爬虫——三、Requests库的基本使用

一.什么是Requests Requests是用Python语言编写,基于urllib,采用Apache2 Licensed开元协议的HTTP库.它比urllib更加的方便,可以节约我们大量的工作完全满足HTTP测试需求.简单来讲,即Python实现的简单易用的HTTP库. 二.Requests库的安装 如果是初学者,建议使用原生Python3进行安装. 1 >> pip3 install requests 如果有一定的Python基础(会基本语法即可),使用anaconda进行安装更加方便,

三、requests模块

Requests: 让 HTTP 服务人类 虽然Python的标准库中 urllib2 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “HTTP for Humans”,说明使用更简洁方便. Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用:) Requests 继承了urllib2的所有特性.Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动确定响

天气预报API(三):免费接口测试(“旧编码”)

说明 我以参考文章为引子,自己测试并扩展,努力寻找更多的气象API... 本文所有测试均以青岛为例. 本文所列接口城市代码(cityid)参数都使用的 "旧编码":全国城市代码列表(旧) 或 全球城市.景点代码 注:另有 "新编码" 的介绍和使用,详见: 全国城市代码列表(新) 1. 国家气象局 当天基础天气接口 http://www.weather.com.cn/data/sk/101120201.html { "weatherinfo": {

api (三)文本字符输出 (转)

在使用Win32编程时,我们常常要输出文本到窗口上,Windows所有的文本字符或者图形输出都是通过图形设备接口(GDI)进行的,Windows的三大核心组件之一的GDI32.dll封装了所有的文本和图像输出. GDI基本知识 Windows下要绘图和输出文本,都是通过GDI(Graphics Device Interface,图形设备接口)完成的,GDI是windows在绘制图文时的设备上下文环境,包括画笔.画刷.字体.位图等多种与绘制有关的对象.设备环境(DC)在绘制中起至关重要的作用.几乎