django-rest-framework(2) 请求与响应

岁酱吖の 提交于 2019-12-26 11:37:03

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

请求对象

restful api提供了下面了几个方法

HTTP方法 行为 示例
GET 获取所有的资源的信息 http://xx.com/api/orders
GET 获取某个特定的资源的信息 http://xx.com/api/orders/2
POST 创建新的资源 http://xx.com/api/orders
PUT 更新资源 http://xx.com/api/orders/1
DELETE 删除资源 http://xx.com/api/orders/1

REST framework扩展了常规的Request,提供了一个更加灵活的HttpRequest方法。其中Request的核心是request.data属性,这个属性类似于request.POST,但是在web apis当中显得更加的灵活

request.POST #仅适用于表单的提交时的操作
request.data #可以适用于做任意的数据,比较'POST','PUT'和'PATCH'方法

###响应对象 rest framework引入了一个Response 对象,它继承自TemplateResponse对象。它获得未渲染的内容并通过内容协商content negotiation 来决定正确的content type返回给client。

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

状态码

rest framework为每个状态码提供了更明确的标记。例如 HTTP_404_NOT_FOUND、HTTP_200_OK、HTTP_201_CREATED 更多.相对于单调的数据而言这类标识符显得更加的直观。

封装API views

在编写api view时,rest framework提供了两个wrappers

  1. The @api_view decorator for working with function based views.
  2. The APIView class for working with class based views.

这两种封装器提供了许多功能,例如,确保在view当中能够接收到Request实例;往Response中增加内容以便内容协商content negotiation 机制能够执行。

汇总

现在我们开始用新的组件编写views 我们不需要再使用JSONResponse类,删除之前在views.py中那部分代码。t我们重新开始重构新的代码.

@api_view(['GET','POST'])
def snippet_list(request):
    '''
        显示所有的snippets列表,或者创建一个新的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 seralizer.is_valid():
            serializer.save()
            return Response(seralizer.data,status=status.HTTP_201_CREATED)
        return Response(seralizer.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)
        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的请求,也可以 输入其他的格式.REST Framework会自动响应正确的内容呈现给client ![屏幕快照 2016-04-12 下午10.38.31](http://7xrkms.com1.z0.glb.clouddn.com/2016-04-12-屏幕快照 2016-04-12 下午10.38.31.png)

###给URLs增加可选的格式后缀 我们在api添加一个后缀 明确指定该url的格式,比如http://example.com/api/items/4.json.的URL. 表示是按json的方法进行处理。 现在我们修改之前的urls.py,只要在后面添加一个format_suffix_patterns(urlpatterns)

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

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

urlpatterns = format_suffix_patterns(urlpatterns)

观看最终效果

我们同样是采用的是之前的port1的方式进行api的测试。

下面的指令是获取snippets的列表 ![屏幕快照 2016-04-12 下午10.47.58](http://7xrkms.com1.z0.glb.clouddn.com/2016-04-12-屏幕快照 2016-04-12 下午10.47.58.png)

我们可以通过包含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

![屏幕快照 2016-04-12 下午10.49.19](http://7xrkms.com1.z0.glb.clouddn.com/2016-04-12-屏幕快照 2016-04-12 下午10.49.19.png) 上面的是以json的方式来进行响应

同样的我们可以使用content-Type控制发送的请求格式 ![屏幕快照 2016-04-12 下午10.52.59](http://7xrkms.com1.z0.glb.clouddn.com/2016-04-12-屏幕快照 2016-04-12 下午10.52.59.png)

同样的我们可以通过浏览器访问来http://127.0.0.1:8000/snippets/ 来进行访问

![屏幕快照 2016-04-12 下午10.54.50](http://7xrkms.com1.z0.glb.clouddn.com/2016-04-12-屏幕快照 2016-04-12 下午10.54.50.png)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!