django rest-framework 2.请求和响应

一、请求对象

REST 框架引入Request来扩展常规的HttpRequest,并提供了更灵活的请求解析。Request对象的核心功能是request.data属性。

导入方式: from rest_framework.response import Request

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采用未呈现的内容,并使用内容协商来确定正确的内容类型以返回给客户端。

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

三、状态码

在Response返回中使用数字HTTP状态码并不总是有助于明显的阅读,REST框架为每一个状态码更明确的标识符,如 HTTP_404_NOT_FOUND 。

导入方式: from rest_framework import status

四、视图装饰器

REST框架提供了两个可用于编写API视图的装饰器

  • @api_view  # 函数装饰器
  • APIView   # 类装饰器

These wrappers provide a few bits of functionality such as making sure you receive Request instances in your view, and adding context to Response objects so that content negotiation can be performed.

The wrappers also provide behaviour such as returning 405 Method Not Allowed responses when appropriate, and handling any ParseError exception that occurs when accessing request.data with malformed input.

五、Pulling it all together

这里不在需要使用JSONResponse来格式化返回数据

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from test_app import serializer
from test_app import models


@api_view(['GET', 'POST'])
def game_list(request):
    if request.method == 'GET':
        games = models.Game.objects.all()
        games_serializer = serializer.Test_app_model_serializer(instance=games, many=True)
        return Response(games_serializer.data)
    elif request.method == 'POST':
        game_serializer = serializer.Test_app_model_serializer(data=request.data)
        if game_serializer.is_valid():
            game_serializer.save()
            return Response(game_serializer.data, status=status.HTTP_201_CREATED)
        return Response(game_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

想相对于之前写的视图函数,这样更加简明扼要,这里是@api_view装饰器的功劳。

这是views.py模块中里一个视图代码

@api_view(['GET', 'PUT', 'DELETE'])
def game_info(request, game_id):
    try:
        game_obj = models.Game.objects.get(id=game_id)
    except models.Game.DoesNotExist as e:
        return Response(status=status.HTTP_404_NOT_FOUND)
        # return HttpResponse(e,status=status.HTTP_404_NOT_FOUND)
    if request.method == 'GET':
        game_serializer = serializer.Test_app_model_serializer(instance=game_obj)
        return Response(game_serializer.data)
    elif request.method == 'PUT':
        game_serializer = serializer.Test_app_model_serializer(instance=game_obj,data=request.data)
        if game_serializer.is_valid():
            game_serializer.save()
            return Response(game_serializer.data)
        return Response(game_serializer.errors)
    elif request.method == 'DELETE':
        game_obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

 六、添加可选的后缀格式

利用REST响应不再是单一的内容类型,可以为API添加对格式后缀的支持,使用格式后缀显示指定格式的返回内容

首先需要在两个视图函数添加一个关键字参数 format ,如下:

def game_list(request, format=None):
def game_info(request, game_id, format=None):

在urls.py中稍微修改文件,在现有的URL之外还附加一组 format_suffix_patterns

from django.conf.urls import url
from test_app import views
from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = [
    url(r'^game_list/',views.game_list),
    url(r'^game_info/(\d+)/', views.game_info),
]
urlpatterns = format_suffix_patterns(urlpatterns)

我们不一定需要添加这些额外的url模式,但它给了我们一个简单,干净的方式来引用特定的格式。

七、如何使用可选的格式后缀

1. 通过 Accept 头来控制回复的格式:

http http://127.0.0.1:8000/game_list/ Accept:application/json  # Request JSON
http http://127.0.0.1:8000/game_list/ Accept:text/html         # Request HTML

2. 通过附加格式后缀

http http://127.0.0.1:8000/game_list.json  # JSON suffix
http http://127.0.0.1:8000/game_list.api   # Browsable API suffix

3. Content-Type 头控制发送的请求格式    http://www.django-rest-framework.org/tutorial/2-requests-and-responses/

# 参考官网
# 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"
}

八、WEB功能

由于API根据客户端请求选择响应的内容类型,因此默认情况下,当Web浏览器请求该资源时,它将返回资源的HTML格式表示。这允许API返回完全可浏览网页的HTML表示。

拥有可浏览网页的API是一个巨大的可用性胜利,并使开发和使用您的API更容易。它也大大降低了其他开发人员检查和使用API​​的障碍。

有关浏览的API功能以及如何自定义API的更多信息,请参阅可浏览的api主题。

posted @ 2017-09-26 18:09  40块钱抓娃娃  阅读(243)  评论(0编辑  收藏  举报