Django REST框架 Requests&Responses

Tutorial 2: request and response

From this point on, we will really begin to cover the core REST framework. Let us introduce a few basic building blocks.

Request Object

REST framework introduces a Requesttarget extended regular HttpRequest, and more flexible request resolution. RequestThe core function of the object is request.dataproperty, which is similar to request.POST, but more useful for using the Web API.

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

Response Object

REST framework also introduces an Responseobject that TemplateResponseuses content that is not presented and use content negotiation to determine the correct content type to be returned to the client.

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

Status Codes

Using a digital HTTP status code in the view does not always show a significant readings, if the error code is an error, it is easy to notice. REST framework provides a more specific identifier for each status code, for example HTTP_400_BAD_REQUESTin the statusmodule. It is always best to use these instead of using the numeric identifier.

View Package API

REST framework provides two packs may be used to write API view.

  1. @api_viewFor processing based on a function of decorator view.
  2. The APIViewview of the working class and class-based.

These packages provide a number of features, such as ensuring that Requestthe receiving instance in view, and to Responseadd to the context object may perform content negotiation.

Packaging also provides behavior, for example 405 Method Not Allowedreturns a response when appropriate, and processing a malformed input ParseErrorany abnormality occurs during access request.data.

put it together

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

We no longer need our JSONResponselesson views.py, so delete it. Once completed, we can begin to reconstruct 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 on the previous example. It is less verbose, and now we are using Forms API code is very similar. We also use named state code, which makes the response more obvious sense.

The following is a views.pyview of the module in a single code segment.

@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 be very familiar with - not much different from using conventional Django view.

Please note that we are no longer explicitly bind our request or response to a given content type. request.dataIt can handle incoming jsonrequests, but it can also handle other formats. Similarly, we return the response object with data, but allows REST framework will be presented to us in response to the correct content type.

Add an optional format in our URL suffix

In order to respond with our not hardwired to a single content type of the fact that we added to the API format API endpoint suffix. Use the suffix format provides a clear reference to the URL given format, which means that we will be able to handle such an API for our http://example.com/api/items/4.json like URL.

First, formatadd the keyword parameter in both views, as follows.

def snippet_list(request, format=None):

with

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

Now snippets/urls.pylittle update file attached to format_suffix_patternsa group other than the conventional URL.

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

urlpatterns = [
    path('snippets/', views.snippet_list),
    path('snippets/<int:pk>', views.snippet_detail),
]

urlpatterns = format_suffix_patterns(urlpatterns)

We do not necessarily need to add these additional url mode, but it provides a simple, clean way for us to refer to a specific format.

Test API

Continue to test the command line API, as we Tutorial Part 1 had done. Although we sent an invalid request, but we have some better error handling method.

We can get a list of all the code segments 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 use Acceptto control the format of the response headers we get:

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

Additional Format or by suffixes:

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 use the Content-Typeheader format of the control request from us.

# 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 are --debugin the httpadd request a switch above, you will be able to see the type of request in the request header.

Now, by accessing http://127.0.0.1:8000/snippets/ , open API in a Web browser.

Reproduced in: https: //www.jianshu.com/p/c192740aa7c4

Guess you like

Origin blog.csdn.net/weixin_34186931/article/details/91068872