DRF - 2.Requests and Responses

本文是我对DRF官网的翻译,并做一些学习笔记。翻译的不是很好,如果有看不懂的建议可以先看看原文,欢迎指正。

原文:2 - Requests and Responses- Django REST framework

从现在开始我们要准备开始接触REST框架的核心部分了。让我们介绍几个基本的构建块。

请求对象Request objects

REST框架引入的Request对象是对常规DjangoHttpRequest对象的扩展,也提供了更灵活的请求解析。Resquest对象的核心功能是request.data属性,它和reqeust.POST很像,但是对于WebAPI来说更有用。

request.POST  # 只处理表单数据,只对POST方法有用
request.data  # 处理任意数据,对POST、PUT、PATCH都有用

响应对象Response objects

REST框架还引入了Response对象,它是一种TemplateResponse类型,它接受未渲染的内容并使用协商来确定正确的内容类型以返回给客户端。

return Response(data)  # Renders to content type as requested by the client.

状态码

在视图中使用数字 HTTP 状态代码并不总能一目了然,而且如果得到错误代码,很容易忽视。 REST框架为每个状态代码提供了更明确的标识符,例如状态模块中的HTTP_400_BAD_REQUEST。最好使用这些而不是使用数字标识符。

包装API视图

REST框架提供了两个装饰器,用来写API视图。

  1. @api_view装饰器,用来处理基于函数的视图
  2. APIView类,用来处理基于类的视图

这些包装提供了一些功能,例如确保您在视图中接收到Request实例,然后向Response对象中添加上下文,以便可以执行内容协商。
这些包装也提供了返回405 Method Not Allowed响应的行为,然后在收到request.data异常数据时处理ParseError异常。

把它们组装起来

好了,现在我们开始用这些新的组件来重构视图。

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)

这对于先前的例子来说,有了一些提升。这更清晰一些,也和Django的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框架渲染成正确的格式。

向URL添加可选的格式后缀

响应不再和单一的内容类型绑定,为了发挥出这个优势,我们为API端点添加对格式后缀的支持。使用格式后缀让URL明确地指向给定的格式,这意味着我们的API可以处理像http://example.com/api/items/4.json这样的URL。
给我们的两个视图加上fomat参数,像这样:

def snippet_list(request, format=None):

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

现在更新snippets/urls.py文件,向已有的URL添加一些额外的format_suffix_patterns

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

urlpatterns = [
    path('snippets/', views.snippet_list),
    path('snippets/<int:pk>', views.snippet_detail),
]

urlpatterns = format_suffix_patterns(urlpatterns)

没有必要把这些额外的URL样式添加进来,不过这为特定的格式提供了一个简单、明了的方式。

现在看起来如何

tutorial part 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标头来控制返回的响应格式:

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

相似的,我们可以用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"
}

如果对上面的http加了--debug参数,那么就能看到请求头里的请求类型了。
现在打开浏览器,浏览一下http:/127.0.0.1:8000/snippets/吧。

可浏览性

由于API会根据客户端请求选择响应的内容类型,因此默认情况下,当 Web 浏览器请求该资源时,它将返回资源的 HTML 格式表示。这允许 API 返回一个完全可通过 Web 浏览的 HTML 表示。
拥有一个可浏览网页的 API 好处非常多,并使开发和使用你的 API 变得更加容易。它还显著降低了其他想要检查和使用您的 API 的开发人员的进入门槛。
有关可浏览 API 功能以及如何自定义它的更多信息,请参阅可浏览browsable api

下一步是什么?

tutorial part 3,我们会开始使用基于类的视图,然后看看通用视图是如何减少我们的代码量的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340