django restful 请求_Django编写RESTful API(二):请求和响应
前言
在上一篇文章,已經實現了訪問指定URL就返回了指定的數據,這也體現了RESTful API的一個理念,每個URL表明著一個資源。固然咱們還知道RESTful API的另外一個特性就是,發送不一樣的請求動做,會返還不一樣的響應,這篇文章就講一下django-rest-framework這個工具在這方面給咱們帶來的便捷操做。django
Request對象
平時咱們在寫Django的視圖函數的時候,都會帶上一個request參數,這樣就能處理平時搭建網站時,瀏覽器訪問網頁時發出的常規的HttpRequest。可是如今咱們導入了django-rest-framework,它可以對request進行拓展,而且提供更靈活的請求解析。這個特性體如今哪呢?請看下面這個例子:json
request.POST #只能處理表單數據.只能處理POST請求
request.data #能處理各類數據。 能夠處理'POST', 'PUT' 和 'PATCH'模式的請求
這個例子里面的注釋已經說得很清楚,拓展后的request使用request.data就能夠處理各類各樣的請求了,而本來的request在處理時須要指定請求模式。api
Response對象
和request對象同樣,django-rest-framework也對其進行了很實用的拓展,在我上一篇文章的snippets/views.py中,咱們導入了JsonResponse用于返回json格式的響應,在視圖函數中是這樣的:瀏覽器
@csrf_exemptdefsnippet_list(request):"""列出全部已經存在的snippet或者建立一個新的snippet"""
if request.method == 'GET':
snippets=Snippet.objects.all()
serializer= SnippetSerializer(snippets, many=True)return JsonResponse(serializer.data, safe=False)elif request.method == 'POST':
data=JSONParser().parse(request)
serializer= SnippetSerializer(data=data)ifserializer.is_valid():
serializer.save()return JsonResponse(serializer.data, status=201)return JsonResponse(serializer.errors, status=400)
也就是說,在return的時候就須要指明json格式,這樣顯得很不實用并且很單一,因此通過拓展后的Reponse對象就很方便了,它會根據客戶端的請求頭部信息來肯定正確的內容類型以返回給客戶端。只需以下代碼:restful
return Response(data)
稍后會改進上一篇文章的程序對此進一步的具體講解。app
狀態碼
咱們知道發送http請求時會返回各類各樣的狀態嗎,可是都是簡單的數字,好比200、404等,這些純數字標識符有時候可能不夠明確或者客戶端在使用的時候不清楚錯誤信息甚至是沒注意看不到,因此django-rest-framework也對此進行了優化,狀態碼會是HTTP_400_BAD_REQUEST、HTTP_404_NOT_FOUND這種,極大的提升可讀性。框架
裝飾API視圖
REST框架還提供了一個裝飾器和一個類來包裝視圖函數,可使用它們來寫API視圖,讓程序能處理的狀況更多。函數
@api_view裝飾器用在基于視圖的方法上。
APIView類用在基于視圖的類上。
注意:本文使用的是基于視圖方法,因此使用的是裝飾器@api_view,APIview這個類暫時不會說起。工具
這兩個東西提供的一些功能,讓咱們省去不少工做,好比說確保你在視圖中收到Request對象或在你的Response對象中添加上下文,這樣就能實現內容通訊。
另外裝飾器能夠在接收到輸入錯誤的request.data時拋出ParseError異常,或者在適當的時候返回405 Method Not Allowed狀態碼。
把這些都使用起來
上面說了這么多拓展和優化,接下來就把它們都使用起來,改進一下本來的snippets/views.py,程序以下:
from rest_framework importstatusfrom rest_framework.decorators importapi_viewfrom rest_framework.response importResponsefrom snippets.models importSnippetfrom snippets.serializers importSnippetSerializer
@api_view(['GET', 'POST'])defsnippet_list(request):"""列出全部已經存在的snippet或者建立一個新的snippet"""
if request.method == 'GET':
snippets=Snippet.objects.all()
serializer= SnippetSerializer(snippets, many=True)returnResponse(serializer.data)elif request.method == 'POST':
serializer= SnippetSerializer(data=request.data)ifserializer.is_valid():
serializer.save()return Response(serializer.data, status=status.HTTP_201_CREATED)return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
能夠看出,通過改進的代碼已經把上面所說的幾個django-rest-framework帶來的特性都應用起來了,咱們能夠看出程序代碼量變少,而且能處理的狀況更多了。 好比說,在本來的視圖函數snippet_detail中,處理'PUT'請求的時候,須要先解析json格式的數據再進一步處理:
data =JSONParser().parse(request)
serializer= SnippetSerializer(snippet, data=data)
也就是說須要分紅兩步實現,并且這里有一個限制就是只能解析json格式的數據流。而改進后的程序只需一行代碼:
serializer = SnippetSerializer(data=request.data)
直接使用以前說的request.data就能夠獲取到提交過來的數據了,而且能夠處理各類數據和各類請求動做,方便了開發。
還有在return的時候也不須要指定json格式了,由本來的
return JsonResponse(serializer.data, status=201)
改為了
return Response(serializer.data,status=status.HTTP_201_CREATED)
這也意味著返回給客戶端的能夠是json或者html等格式的內容,返回HTML格式的內容的話,會在瀏覽器返回通過渲染的、更美觀的頁面。同時能夠看出狀態碼也改進成了django-rest-framework給咱們帶來的可讀性更高的狀態標識碼,以上這些措施都很大程度的提升了對客戶的友好度。
對于另外一個視圖函數的修改也是一樣的原理,這里就不作一樣的講解了,代碼以下:
@api_view(['GET', 'PUT', 'DELETE'])defsnippet_detail(request, pk):"""Retrieve, update or delete a snippet instance."""
try:
snippet= Snippet.objects.get(pk=pk)exceptSnippet.DoesNotExist:return Response(status=status.HTTP_404_NOT_FOUND)if request.method == 'GET':
serializer=SnippetSerializer(snippet)returnResponse(serializer.data)elif request.method == 'PUT':
serializer= SnippetSerializer(snippet, data=request.data)ifserializer.is_valid():
serializer.save()returnResponse(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提交過來的數據不須要必定是json格式的數據,返回的響應也不須要必定是json數據,也能夠是通過渲染的HTML頁面。稍后就會示范使用。
向URL添加可選的格式后綴
既然上面已經說了返回給客戶端的Response但是json或者是HTML等格式的內容,那么用戶在使用的時候是如何指定返回哪一種格式的內容呢,那就是在URL的最后加上后綴。好比http://127.0.0.1:8000/snippets.json,這樣就是用戶本身指定了返回json格式的Response,而不是咱們在后臺指定返回固定的格式。
只需對咱們的程序稍加改進就能夠了,在兩個視圖函數添加關鍵詞參數format:
def snippet_list(request, format=None):
以及
def snippet_detail(request, pk, format=None):
再修改一下snippets/urls.py,導入format_suffix_patterns(格式后綴模式):
from django.conf.urls importurlfrom rest_framework.urlpatterns importformat_suffix_patternsfrom snippets importviews
urlpatterns=[
url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P[0-9]+)$', views.snippet_detail),
]
urlpatterns= format_suffix_patterns(urlpatterns)
改進后的使用
首先固然仍是能夠像上一篇文章中那樣的使用:
也能夠經過設置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
效果以下(返回的是頁面的HTML代碼,只展現了一部分):
還能夠直接加格式后綴:
http http://127.0.0.1:8000/snippets.json #JSON suffix
http http://127.0.0.1:8000/snippets.api #Browsable API suffix
固然啦,在命令行查看HTML代碼就沒啥意思了,咱們能夠直接在瀏覽器輸入 http://127.0.0.1:8000/snippets.api 進行查看,會獲得一個美觀的頁面:
若是咱們要增添數據怎么辦?咱們能夠控制 Content-Type 頭部信息來提交POST請求:
http --form POST http://127.0.0.1:8000/snippets/ code="print 123"http--json POST http://127.0.0.1:8000/snippets/ code="print 456"
它會自動在原有的數據后面添加你提交過去的數據,效果以下:
上面說了,改進后能夠處理錯誤的提交,好比把code改為了codes,就會給出錯誤信息:
圖中給出的錯誤信息是 400 Bad Request,這和咱們在視圖函數中定義的是同樣的:
return Response(serializer.data,status=status.HTTP_400_BAD_REQUEST)
在請求中若是加入了--debug能夠查看到詳細的請求信息和類型:
在上面介紹@api_view和APIView的時候,提到了在適當的時候返回405 Method Not Allowed狀態碼。這個所謂適當的時候就要回看到剛才寫視圖函數的時候,修飾器的代碼:
@api_view(['GET','POST'])
以及
@api_view(['GET','PUT','DELETE'])
這兩行代碼就規定了在調用這兩個函數,也就是訪問到相關的URL時,只能使用指定的請求動做,不然就會報出405 Method Not Allowed錯誤。例如訪問 http://127.0.0.1:8000/snippets.json 時用了PUT請求就會報這個錯:
正確的更改數據應該以下:
http --json PUT http://127.0.0.1:8000/snippets/1.json code="hello world"
這樣就把 id=1 的數據修改了。想要刪除也是同樣的:
這樣就能夠把 id=3 的數據刪除掉了。
OK,關于Django RESTful API的請求和響應部分的處理就先講到這了。下一篇會介紹基于類的視圖,多謝支持~
本文地址:http://www.cnblogs.com/zivwong/p/7427394.html
做者博客:ziv
歡迎轉載,請在明顯位置給出出處及連接
總結
以上是生活随笔為你收集整理的django restful 请求_Django编写RESTful API(二):请求和响应的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 特种部队狙击手执行任务时究竟瞄哪里
- 下一篇: u盘插上怎么显示怎么办啊 U盘插上无反应