django rest framework 入門2——Request and Response

從本節我們開始真正接觸rest framework的核心部分。首先我們學習一下一些必備知識。


1. Request Object  ——Request對象

rest framework 引入了一個繼承自HttpRequest的Request對象,該對象提供了對請求的更靈活解析。request對象的核心部分是request.data屬性,類似於request.post, 但在使用WEB API時,request.data更有效。

request.POST  # Only handles form data.  Only works for 'POST' method.
request.DATA  # Handles arbitrary data.  Works any HTTP request with content.
2. Response Object ——Response對象

rest framework引入了一個Response 對象,它繼承自TemplateResponse對象。它獲得未渲染的內容並通過內容協商content negotiation 來決定正確的content type返回給client。

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

在views當中使用數字化的HTTP狀態碼,會使你的代碼不宜閱讀,且不容易發現代碼中的錯誤。rest framework爲每個狀態碼提供了更明確的標識。例如HTTP_400_BAD_REQUEST。相比於使用數字,在整個views中使用這類標識符將更好。


4. 封裝API views

在編寫API views時,REST Framework提供了兩種wrappers:

1).  @api_viwe 裝飾器 ——函數級別

2). APIView 類——類級別

這兩種封裝器提供了許多功能,例如,確保在view當中能夠接收到Request實例;往Response中增加內容以便內容協商content negotiation 機制能夠執行。

封裝器也提供一些行爲,例如在適當的時候返回405 Methord Not Allowed響應;在訪問多類型的輸入request.DATA時,處理任何的ParseError異常。


5. 彙總

我們開始用這些新的組件來寫一些views。

我們不在需要JESONResponse 類(在前一篇中創建),將它刪除。刪除後我們開始稍微重構下我們的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):
    """
    List all snippets, or create a new snippet.
    """
    if request.method == 'GET':
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets)
        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)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
上面的代碼是對我們之前代碼的改進。看上去更簡潔,也更類似於django的forms api形式。我們也採用了狀態碼,使返回值更加明確。

下面是對單個snippet操作的view更新:

@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)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
注意,我們並沒有明確的要求requests或者responses給出content type。request.DATA可以處理輸入的json請求,也可以輸入yaml和其他格式。類似的在response返回數據時,REST Framework返回正確的content type給client。


6. 給URLs增加可選的格式後綴

利用在response時不需要指定content type這一事實,我們在API端增加格式的後綴。使用格式後綴,可以明確的指出使用某種格式,意味着我們的API可以處理類似http://example.com/api/items/4.json.的URL。

增加format參數在views中,如:

def snippet_list(request, format=None):

and

def snippet_detail(request, pk, format=None):
現在稍微改動urls.py文件,在現有的URLs中添加一個格式後綴pattterns (format_suffix_patterns):

from django.conf.urls import patterns, url
from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = patterns('snippets.views',
    url(r'^snippets/$', 'snippet_list'),
    url(r'^snippets/(?P<pk>[0-9]+)$', 'snippet_detail'),
)

urlpatterns = format_suffix_patterns(urlpatterns)

這些額外的url patterns並不是必須的。


來源:

http://django-rest-framework.org/tutorial/2-requests-and-responses.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章