從這一片來講,咱們將真正開始覆蓋REST框架的核心。咱們來介紹一些基本的構建塊html
REST框架引入了一個Request擴展常規的對象HttpRequest,並提供更靈活的請求解析。Request對象的核心功能是request.data,和之相似的屬性request.POST,但比request.POST更爲有用。python
request.POST # Only handles form data. Only works for 'POST' method. request.data # Handles arbitrary data. Works for 'POST', 'PUT' and 'PATCH' methods.
REST框架還引入了一個Response對象,它是一種類型的對象,它TemplateResponse使用未呈現的內容並使用內容協商來肯定返回給客戶端的正確內容類型。django
return Response(data) # Renders to content type as requested by the client.
在視圖中使用數字HTTP狀態代碼並不易見的閱讀,而且若是代碼錯誤,並不很容易注意到。REST框架爲每一個狀態代碼提供更明確的標識符,例如HTTP_400_BAD_REQUEST在status模塊中。這是一個好主意,而不是使用數字標識符。json
REST框架提供了兩個可用於編寫API視圖的包裝器。api
@api_view用於處理基於函數的視圖的裝飾器。
該APIView班與基於類的視圖工做。
這些包裝提供了一些功能,例如確保Request在視圖中接收實例,並向Response對象添加上下文,以即可以執行內容協商。app
這些包裝器還提供了一些行爲,例如405 Method Not Allowed在適當時返回響應,以及處理ParseError在request.data格式錯誤的輸入中訪問時發生的任何異常。框架
好的,讓咱們繼續,開始使用這些新的組件。函數
讓咱們從新編寫上面關於序列化的項目,從新編寫上面view裏面的內容測試
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, format=None): """ 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, format=None): """ 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)
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頭來控制返回的響應的格式rest
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
# 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" }