转载自:http://www.django-rest-framework.org/tutorial/2-requests-and-responses/

Tutorial 2: Requests and Responses

From this point we're going to really start covering the core of REST framework. Let's introduce a couple of essential building blocks.

Request objects

REST framework introduces a Request object that extends the regular HttpRequest, and provides more flexible request parsing. The core functionality of the Request object is the request.data attribute, which is similar to request.POST, but more useful for working with Web APIs.

request.POST  # Only handles form data.  Only works for 'POST' method. request.data # Handles arbitrary data. Works for 'POST', 'PUT' and 'PATCH' methods.

Response objects

REST framework also introduces a Response object, which is a type of TemplateResponse that takes unrendered content and uses content negotiation to determine the correct content type to return to the client.

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

Status codes

Using numeric HTTP status codes in your views doesn't always make for obvious reading, and it's easy to not notice if you get an error code wrong. REST framework provides more explicit identifiers for each status code, such as HTTP_400_BAD_REQUEST in the status module. It's a good idea to use these throughout rather than using numeric identifiers.

Wrapping API views

REST framework provides two wrappers you can use to write API views.

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

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

Okay, let's go ahead and start using these new components to write a few views.

We don't need our JSONResponse class in views.py any more, so go ahead and delete that. Once that's done we can start refactoring our views slightly.

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): """ 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)

Our instance view is an improvement over the previous example. It's a little more concise, and the code now feels very similar to if we were working with the Forms API. We're also using named status codes, which makes the response meanings more obvious.

Here is the view for an individual snippet, in the views.py module.

@api_view(['GET', 'PUT', 'DELETE']) def snippet_detail(request, pk): """ 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)

This should all feel very familiar - it is not a lot different from working with regular Django views.

Notice that we're no longer explicitly tying our requests or responses to a given content type.  request.data can handle incoming json requests, but it can also handle other formats. Similarly we're returning response objects with data, but allowing REST framework to render the response into the correct content type for us.

Adding optional format suffixes to our URLs

To take advantage of the fact that our responses are no longer hardwired to a single content type let's add support for format suffixes to our API endpoints. Using format suffixes gives us URLs that explicitly refer to a given format, and means our API will be able to handle URLs such as http://example.com/api/items/4.json.

Start by adding a format keyword argument to both of the views, like so.

def snippet_list(request, format=None):

and

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

Now update the urls.py file slightly, to append a set of format_suffix_patterns in addition to the existing URLs.

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)

We don't necessarily need to add these extra url patterns in, but it gives us a simple, clean way of referring to a specific format.

How's it looking?

Go ahead and test the API from the command line, as we did in tutorial part 1. Everything is working pretty similarly, although we've got some nicer error handling if we send invalid requests.

We can get a list of all of the snippets, as before.

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" } ]

We can control the format of the response that we get back, either by using the Accept header:

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

Or by appending a format suffix:

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

Similarly, we can control the format of the request that we send, using the Content-Type header.

# 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" }

If you add a --debug switch to the http requests above, you will be able to see the request type in request headers.

Now go and open the API in a web browser, by visiting http://127.0.0.1:8000/snippets/.

Browsability

Because the API chooses the content type of the response based on the client request, it will, by default, return an HTML-formatted representation of the resource when that resource is requested by a web browser. This allows for the API to return a fully web-browsable HTML representation.

Having a web-browsable API is a huge usability win, and makes developing and using your API much easier. It also dramatically lowers the barrier-to-entry for other developers wanting to inspect and work with your API.

See the browsable api topic for more information about the browsable API feature and how to customize it.

What's next?

In tutorial part 3, we'll start using class-based views, and see how generic views reduce the amount of code we need to write.

转载于:https://www.cnblogs.com/kaid/p/8011214.html

Tutorial 2: Requests and Responses相关推荐

  1. [转]Open Data Protocol (OData) Basic Tutorial

    本文转自:http://www.odata.org/getting-started/basic-tutorial/ Basic Tutorial The Open Data Protocol (ODa ...

  2. How to debug HTTP requests when developing and testing Web applications and clients

    How to debug HTTP requests when developing and testing Web applications and clients How to debug HTT ...

  3. flask部署机器学习_如何开发端到端机器学习项目并使用Flask将其部署到Heroku

    flask部署机器学习 There's one question I always get asked regarding Data Science: 关于数据科学,我经常被问到一个问题: What ...

  4. Redis 性能问题分析(好文推荐)

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者: 刘思宁 整理:朱小厮 www.jianshu.com/p/ ...

  5. 硬货 | Redis 性能问题分析

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:rrd.me/gteAC 在一些网络服务的系统中,Redis ...

  6. Redis 性能问题分析

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 刘思宁 来源 | jianshu.com/p/ ...

  7. 面向.NET开发人员的Dapr——可观察性

    目录: 面向.NET开发人员的Dapr--前言 面向.NET开发人员的Dapr--分布式世界 面向.NET开发人员的Dapr--俯瞰Dapr 面向.NET开发人员的Dapr--入门 面向.NET开发人 ...

  8. express-cli入门_使用Express.js入门

    express-cli入门 by Victor Ofoegbu 由Victor Ofoegbu 使用Express.js入门 (Getting off the ground with Express. ...

  9. Spring WS Consume Soap Service From WSDL

    2019独角兽企业重金招聘Python工程师标准>>> Spring WS Consume Soap Service From WSDL BY MEMORYNOTFOUND · DE ...

最新文章

  1. 知识图谱可解释推理研究综述
  2. itoa函数和atoi函数
  3. .DLL文件是什么?
  4. linux ksh 历史命令,防止Linux中的bash(和ksh)历史记录更改
  5. python温度转换程序_用Python程序温度转换实例
  6. JBoss AS 7.1.0.Final“ Thunder”发布-Java EE 6 Full Profile认证!
  7. android旋转屏幕 简册,[Android][旋转屏幕]
  8. Python入门:ChainMap 有效管理多个上下文
  9. Spring入门学习手册 6:Spring MVC基础中的基础
  10. 人工智能在计算机视觉方面的应用3000字,人工智能之计算机视觉应用专题报告.pptx...
  11. 防止页面高度不足,引起的底部上浮问题
  12. nc windows安装教程
  13. Java程序调用linux脚本-简单版
  14. 安徽大学高等数学习题册(上)(第一章)
  15. Pr全套视频教程 PR 全套零基础从入门到精通视频教程
  16. 戴德金--连续性和无理数--我自己做的中文翻译第4页
  17. ppurl 下载电子书
  18. 灵隐寺招聘员工:没有KPI,佛系上班,四点半下班……
  19. 让生态更有力量 CDEC2020中国数字智能生态大会成都站圆满收官
  20. 防追踪创安全网络环境 EFF推Beta版“Privacy Badger”扩展

热门文章

  1. 【opencv 学习】【常用的图像卷积核】
  2. leetcode —— 589. N叉树的前序遍历 (使用到遍历多叉树的方法)
  3. leetcode - 1223. 掷骰子模拟
  4. 中国计算机学会推荐的国际学术刊物
  5. Python矩阵计算
  6. OpenCV--实现图像滑动窗口截取子图操作
  7. 矩阵特征值和特征向量详细计算过程(转载)
  8. Redis简介及配置文件介绍
  9. Spring框架 简述
  10. 迁移学习 Transfer Learning—通俗易懂地介绍(常见网络模型pytorch实现)