您的位置:首页 > 产品设计 > UI/UE

Django-Rest-Framework 教程: 2. Requests 和 Responses

2014-10-01 11:34 633 查看
作者: Desmond
Chen, 发布日期: 2014-05-30, 修改日期: 2014-05-30

接着上篇的内容,
本篇中, 我们进一步介绍Django-rest-framework的其他核心部件. 首先我们来做准备工作:


Request

django-rest-framework中引入了新的Request类, 该Request继承自Django的HttpRequest, 并提供了更多灵活的request处理功能. 比如request.DATA属性便是专门用作Web API的属性, 类似于request.POST.
request.POST  # 只处理form数据; 只接受HTML 'POST'动作.
request.DATA  # 处理特定数据; 接受HTML 'POST', 'PUT' 和 'PATCH' 动作.


状态码 (status codes)

django-rest-framework为每一个状态码都提供了打包好的, 更为精确的状态码完整描述供我们使用, 比如HTTP_400_BAD_REQUEST.


API views

django-rest-framework为function_based_view和class_based_view分别提供了@api_view修饰器和APIView类. 这些wrapper代码, 保证了view接收Request实例, 并会自动添加context至Response中. 这些wrapper还能自动返回正确的状态码和详细信息.


1. 开始

接着之前的views.py, 在这里, 我们已经不需要JSONResponse了, 因此, 首先将其删除. 然后修改views.py中的snippet_list view:
snippets/views.py
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):
"""
展示所有存在的snippet, 或建立新的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)


以上代码相对于教程1中的代码更为简洁. 可以看到代码与form API的使用十分相似, 我们还使用了内置的状态码, 使返回的response意义更为清晰.

对于单独的snippet编辑:
@api_view(['GET', 'PUT', 'DELETE'])
def snippet_detail(request, pk):
"""
展示, 更新或删除一个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)


从以上代码中可以看到, 我们不再指明request和response中的内容类型. request.DATA即可用来处理json数据类型类型, 也可以处理yaml或其他数据类型. 同时, django-rest-framework也能根据不同情况, 再response呈现正确的数据类型.


2. 使用其他数据格式

为了展示如何多数据格式的支持, 接下来, 我们为url添加后缀: http://example.com/api/items/4.json
为snippets/view.py中的snippet_list和snippet_detail增加format参数
def snippet_list(request, format=None):
...

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


更新urls.py:
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 pattern就能实现多数据格式的支持. 但添加之后使得使用时更加直观.


3. 测试

我们可以通过前篇教程中的方式测试, 获取所有snippet:
curl http://127.0.0.1:8000/snippets/ 
[{"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头部信息控制response返回格式:
curl http://127.0.0.1:8000/snippets/ -H 'Accept: application/json'  # JSON
curl http://127.0.0.1:8000/snippets/ -H 'Accept: text/html'         # HTML


或者使用后缀控制返回格式:
curl http://127.0.0.1:8000/snippets/.json  # JSON suffix
curl http://127.0.0.1:8000/snippets/.api   # Browsable API suffix


通过修改request的Content-Type头部, 控制格式:
# 使用form data POST
curl -X POST http://127.0.0.1:8000/snippets/ -d "code=print 123"

{"id": 3, "title": "", "code": "print 123", "linenos": false, "language": "python", "style": "friendly"}

# 使用JSON POST
curl -X POST http://127.0.0.1:8000/snippets/ -d '{"code": "print 456"}' -H "Content-Type: application/json"

{"id": 4, "title": "", "code": "print 456", "linenos": true, "language": "python", "style": "friendly"}


或者直接在浏览器中打开:
http://127.0.0.1:8000/snippets/[/code] 
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: