Request objects
The REST Framework introduces Request对象来 extended routines HttpRequest and provides more flexible request resolution. The core request.data function of an object is a property, which Request request.POST相似,但对 using the Web API more useful.
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
The rest framework also introduces an Response object that TemplateResponse的一种类型,它 uses content that is not rendered 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 a digital HTTP status code in your view is not always conducive to reading, and if you receive an error code wrong you will find it hard to notice. The rest framework has a more explicit identifier for each status code, such as status in the module HTTP_400_BAD_REQUEST。 Using these identifiers is much better than using numeric identifiers.
Wrapping API views
The rest framework provides two wrappers that can be used to write API views.
@api_viewthe adorner is valid for function-based views.
APIViewThe class is valid for class-based views.
These wrappers provide features such as ensuring that you receive Request instances in a view and adding contexts to Response objects so that you can perform content negotiation.
The wrappers also provide behaviour such as returning 405 Method Not Allowed responses when appropriate, and handling any ParseError exception t Hat occurs when accessing with request.data malformed input.
Pulling it all together
OK, let's start using these new components to write a few views.
views.py中class is no longer required JSONResponse , so please delete it. Once this is done, we can begin to refactor our view.
From rest_framework import statusfrom rest_framework.decorators import api_viewfrom rest_framework.response Import ResponseFrom snippets.models import snippetfrom snippets.serializers import Snippetserializer@api_view ([' GET ', ' POST '])def snippet_list (Request): "" "List all snippets, or create a new snippet. "" "If request.method = = ' GET ': snippets = Snippet.objects.all () serializer = Snippetserializer (snippets, Many=true) returnResponse(serializer.data) elif Request.method = = ' POST ': serializer = Snippetserializer (data=Request.data) if Serializer.is_valid (): Serializer.save () returnResponse(Serializer.data, status=status. Http_201_created) returnResponse(Serializer.errors, status=status. Http_400_bad_request)
Our instance view has improved compared to previous examples. This is more concise, and the code today is very similar to the Forms API we use. We also use named status codes, which makes the response more obvious.
Below are views.py A single piece of code snippet view in the module.
@api_view ([' GET ', ' PUT ', ' DELETE ']) def snippet_detail (Request, PK): "" "Retrieve, update or DELETE a snippet Instanc E. "" "Try:snippet = Snippet.objects.get (pk=pk) except Snippet.DoesNotExist:returnResponse(status=status. Http_404_not_foundif Request.method = = ' GET ': Serializer = Snippetserializer (snippet) returnResponse(serializer.data) elif Request.method = = ' PUT ': Serializer = Snippetserializer (snippet, data=Request.data) if Serializer.is_valid (): Serializer.save () returnResponse(Serializer.data) returnResponse(Serializer.errors, status=status. Http_400_bad_request) elif Request.method = = ' DELETE ': Snippet.delete () returnResponse(status=status. Http_204_no_content)
This should all be very familiar-not unlike the regular Django view.
Note that we no longer explicitly bind our request or response to a given content type. request.data can handle input json requests, but it can also handle other formats. again, we use the data to return the response object, but allow the rest framework to render the response as the correct content type.
Adding Optional format suffixes to our URLs
Our response is no longer connected to a single content type, and to take advantage of this fact, we can add some format suffixes to the API endpoint. use the format suffix to explicitly specify a format for URLs, which means that our API will be able to handle things like Http://example.com/api/items/4.json and the like Urls.
first Add one format of the two views keyword parameters, just like this.
def snippet_list (Request, Format=none):
and
def snippet_detail (Request, PK, Format=none):
now slightly update the urls.py file, plus a set of URLs that already existformat_suffix_patterns。
From django.conf.urls import URL fromrest_framework.urlpatterns import format_suffix_patternsfrom snippets Import viewsurlpatterns = [ 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 additional URL patterns, but it gives us a simple, clean way to reference a particular format.
How ' s it looking?
Start testing the API from the command line, as we did in part 1th. All work is very similar, although we have better error handling if we send invalid requests.
We can get a list of all the fragments as before.
HTTP http://127.0.0.1:8000/snippets/HTTP/1.1-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 do this by using Accept header to control the format of the response :
HTTP Http://127.0.0.1:8000/snippets/Accept:application/json # Request Jsonhttp http://127.0.0.1:8000/snippets /accept:text/html # Request HTML
or by appending the format suffix:
HTTP Http://127.0.0.1:8000/snippets.json # JSON suffixhttp http://127.0.0.1:8000/snippets.api # browsable API suffix
Similarly, Similarly, we can use Content-Type header to control the format of requests we send.
# Post using form datahttp--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 Jsonhttp- -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 http to the requests above, you'll be able to see the request for type in request headers.
If you add --debug a requests to the above HTTP , you will be able to view the request type in the request header.
Now, open the API in a Web browser and access http://127.0.0.1:8000/snippets/.
API (iii) requests and responses