REST框架引入了一个扩展常规的对象,并提供更灵活的请求解析。该对象的核心功能是属性,它类似于 ,但对于使用 Web API 更有用。
request.POST # 只处理表单数据。仅适用于"POST"方法。
request.data # 处理任意数据。适用于"POST"、"PUT"和"PATCH"方法。
REST 框架还引入了一个对象,该对象是一种获取未渲染内容并使用内容协商来确定要返回给客户端的正确内容类型。
return Response(data) # 根据客户端的请求呈现为内容类型。
在视图中使用数字 HTTP 状态代码并不总是能带来明显的阅读效果,如果错误代码出错,也很容易不注意到。REST 框架为每个状态代码(如模块中)提供了更明确的标识符。最好始终使用这些标识符,而不是使用数字标识符。
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)
@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)
了利用我们的响应不再硬连接到单个内容类型的事实,让我们向 API 终结点添加对格式后缀的支持。使用格式后缀可以为我们提供显式引用给定格式的URL,API将能够处理诸如 http://example.com/api/items/4.json
之类的URL。
首先向这两个视图添加一个关键字参数,如下所示。format
def snippet_list(request, format=None):
和
def snippet_detail(request, pk, format=None):
现在稍微更新文件,以附加一组除现有 URL 之外的 URL
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/', views.snippet_detail),
]
urlpatterns = format_suffix_patterns(urlpatterns)
我们不一定需要添加这些额外的url模式,但它为我们提供了一种简单,干净的方式来引用特定格式。
url后缀格式使用:
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"
}
如果将开关添加到上述请求中,您将能够在请求标头中看到请求类型。–debughttp
现在,通过访问 http://127.0.0.1:8000/snippets/,在Web浏览器中打开API。