diff options
Diffstat (limited to 'docs/tutorial/2-requests-and-responses.md')
| -rw-r--r-- | docs/tutorial/2-requests-and-responses.md | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index 603edd08..c0426969 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -5,10 +5,10 @@ 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. +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. + request.data # Handles arbitrary data. Works for 'POST', 'PUT' and 'PATCH' methods. ## Response objects @@ -29,11 +29,11 @@ REST framework provides two wrappers you can use to write API 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. +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. +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` anymore, so go ahead and delete that. Once that's done we can start refactoring our views slightly. @@ -55,7 +55,7 @@ We don't need our `JSONResponse` class in `views.py` anymore, so go ahead and de return Response(serializer.data) elif request.method == 'POST': - serializer = SnippetSerializer(data=request.DATA) + serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) @@ -69,7 +69,7 @@ Here is the view for an individual snippet, in the `views.py` module. def snippet_detail(request, pk): """ Retrieve, update or delete a snippet instance. - """ + """ try: snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: @@ -80,7 +80,7 @@ Here is the view for an individual snippet, in the `views.py` module. return Response(serializer.data) elif request.method == 'PUT': - serializer = SnippetSerializer(snippet, data=request.DATA) + serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) @@ -92,7 +92,7 @@ Here is the view for an individual snippet, in the `views.py` module. 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 `yaml` and 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. +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 `yaml` and 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 @@ -110,12 +110,13 @@ Now update the `urls.py` file slightly, to append a set of `format_suffix_patter from django.conf.urls import patterns, 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 = patterns('snippets.views', - url(r'^snippets/$', 'snippet_list'), - url(r'^snippets/(?P<pk>[0-9]+)$', '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. @@ -126,31 +127,64 @@ Go ahead and test the API from the command line, as we did in [tutorial part 1][ We can get a list of all of the snippets, as before. - 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"}] + 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: - curl http://127.0.0.1:8000/snippets/ -H 'Accept: application/json' # Request JSON - curl http://127.0.0.1:8000/snippets/ -H 'Accept: text/html' # Request HTML + 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: - curl http://127.0.0.1:8000/snippets/.json # JSON suffix - curl http://127.0.0.1:8000/snippets/.api # Browsable API 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 - curl -X POST http://127.0.0.1:8000/snippets/ -d "code=print 123" + 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 - curl -X POST http://127.0.0.1:8000/snippets/ -d '{"code": "print 456"}' -H "Content-Type: application/json" + { + "id": 3, + "title": "", + "code": "print 123", + "linenos": false, + "language": "python", + "style": "friendly" + } - {"id": 4, "title": "", "code": "print 456", "linenos": true, "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" + } Now go and open the API in a web browser, by visiting [http://127.0.0.1:8000/snippets/][devserver]. |
