从这一片来讲,咱们将真正开始覆盖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" }