Django REST 프레임워크 학습 노트Tutorial 2 Requests and Responses

13134 단어

Request 객체


REST 프레임워크는 Request 대상을 도입하여 HttpRequest에 계승했다. HttpRequest에 비해 더 많은 요청 해석을 제공했다. 가장 핵심적인 기능은 request.data 속성인데 request.POST과 유사하다. 다음은 다른 점이다.
  • request.POST
  • 은form표 데이터만 처리할 수 있습니다.
  • 은 POST 요청만 처리할 수 있습니다.
  • request.data
  • 은 임의의 데이터를 처리할 수 있다.

  • POST, PUT, PATCH 요청을 처리하는

    Response 객체


    REST 프레임워크도 Response 대상을 도입했는데 이것은 TemplateResponse 형식으로 처리되지 않은 텍스트를 적당한 형식으로 바꾸어 클라이언트에게 되돌려줄 수 있다
    return Response(data)
    

    상태 코드


    REST 프레임워크는 HTTP_400_BAD_REQUEST과 같은 읽을 수 있는 상태 정보를 제공합니다.

    API views 캡슐화

  • 함수 views의 경우 @api_view 장식기
  • 사용 가능
  • 은 클래스 views에 대해 APIView
  • 에 상속될 수 있다

    views 응용 프로그램


    수정 snippets/views.py
  • GET 전체 code snippets 확보, 신규 code snippet 인터페이스
  • 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)
    
  • GET 획득 1개 code snippet PUT 업데이트 1개 code snippet DELETE 삭제 1개 code snippet
  • @api_view(['GET', 'PUT', 'DELETE'])
    def snippet_detail(request, pk):
        """
        retrieve, update or delete code snippet
        """
        try:
            snippet = Snippet.objects.get(pk=pk)
        except Snippet.DoseNotExist:
            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.errors, status=status.HTTP_400_BAD_REQUEST)
    
        elif request.method == 'DELETE':
            snippet.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
    

    이전 단계의 views과 현저히 다른 것은 입력(request) 출력(response)의 데이터 형식에 관심을 두지 않아도 된다는 것이다. REST 프레임워크는 이미 우리를 도와 처리했다.

    URLs에 대한 옵션 형식 접미어 추가


    위에서 말한 바와 같이 REST 프레임워크는 입력(request) 출력(response)의 데이터 형식을 처리해 주었다. 이것은 하나의 API가 서로 다른 데이터 형식을 처리할 수 있다는 것을 의미한다. URLs에서 포맷 접두사를 사용하면 이와 유사한 URl:http://192.168.0.103/snippets.json을 처리할 수 있다.
  • 우선 views에 인삼 format=None
  • 을 추가해야 합니다.
    def snippet_list(request, format=None):
    
    def snippet_list(request, format=None):
    
  • 그리고 urls.py
  • 수정
    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[0-9]+)$', views.snippet_detail),
    ]
    
    urlpatterns = format_suffix_patterns(urlpatterns)
    

    호출 인터페이스

  • 은 서버를 시작하기 전에 settings.pyALLOWED_HOSTS을 수정하여 나중에 외부 브라우저를 통해 인터페이스를 요청할 수 있도록
  • ALLOWED_HOSTS = ['*']
    
  • 서버 부팅(시간에 상관없이 매일 저녁에 돌아와서 Win10을 수면 상태에서 회복시키면 가상 기기의 IP와 시간대는 항상 변한다. (매번 귀찮아서 바꾸지 않는다)
  • (django_rest_framework) [root@localhost tutorial]# python manage.py runserver 0:80
    Performing system checks...
    
    System check identified no issues (0 silenced).
    November 21, 2017 - 02:47:02
    Django version 1.11.7, using settings 'tutorial.settings'
    Starting development server at http://0:80/
    Quit the server with CONTROL-C.
    
  • 다른 셸 창을 열고 요청을 보내기
  • (django_rest_framework) [root@localhost django_rest_framework]# http http://127.0.0.1:80/snippets/
    HTTP/1.0 200 OK
    Allow: POST, GET, OPTIONS
    Content-Length: 505
    Content-Type: application/json
    Date: Mon, 20 Nov 2017 18:51:07 GMT
    Server: WSGIServer/0.2 CPython/3.6.3
    Vary: Accept, Cookie
    X-Frame-Options: SAMEORIGIN
    
    [
        {
            "code": "foo = \"bar
    \"", "id": 1, "language": "python", "linenos": false, "style": "friendly", "title": "" }, { "code": "print \"hello, world\"
    ", "id": 2, "language": "python", "linenos": false, "style": "friendly", "title": "" }, ... ]
  • 데이터를 반환하는 데이터 유형을 제어하기 위해 HTTP HEADERS를 추가할 수 있음
  • json
  • (django_rest_framework) [root@localhost django_rest_framework]# http http://127.0.0.1:80/snippets/ Accept:application/json
    HTTP/1.0 200 OK
    Allow: POST, GET, OPTIONS
    Content-Length: 505
    Content-Type: application/json
    Date: Mon, 20 Nov 2017 18:52:27 GMT
    Server: WSGIServer/0.2 CPython/3.6.3
    Vary: Accept, Cookie
    X-Frame-Options: SAMEORIGIN
    
    [
        {
            "code": "foo = \"bar
    \"", "id": 1, "language": "python", "linenos": false, "style": "friendly", "title": "" }, { "code": "print \"hello, world\"
    ", "id": 2, "language": "python", "linenos": false, "style": "friendly", "title": "" }, ]
  • html
  • (django_rest_framework) [root@localhost django_rest_framework]# http http://127.0.0.1:80/snippets/ Accept:text/html
    HTTP/1.0 200 OK
    Allow: POST, GET, OPTIONS
    Content-Length: 8139
    Content-Type: text/html; charset=utf-8
    Date: Mon, 20 Nov 2017 18:53:39 GMT
    Server: WSGIServer/0.2 CPython/3.6.3
    Vary: Accept, Cookie
    X-Frame-Options: SAMEORIGIN
    
    
    
      
        
    
          
            
            
          
    
          Snippet List – Django REST framework
    
          
            
              
    ...
    
  • 또는 url 접두사를 직접 추가하여 데이터를 되돌려주는 데이터 형식을 제어할 수 있습니다
  • json
  • (django_rest_framework) [root@localhost django_rest_framework]# http http://127.0.0.1:80/snippets.json
    HTTP/1.0 200 OK
    Allow: POST, GET, OPTIONS
    Content-Length: 505
    Content-Type: application/json
    Date: Mon, 20 Nov 2017 18:55:27 GMT
    Server: WSGIServer/0.2 CPython/3.6.3
    Vary: Accept, Cookie
    X-Frame-Options: SAMEORIGIN
    
    [
        {
            "code": "foo = \"bar
    \"", "id": 1, "language": "python", "linenos": false, "style": "friendly", "title": "" }, { "code": "print \"hello, world\"
    ", "id": 2, "language": "python", "linenos": false, "style": "friendly", "title": "" }, ... ]
  • html
  • (django_rest_framework) [root@localhost django_rest_framework]# http http://127.0.0.1:80/snippets.api
    HTTP/1.0 200 OK
    Allow: POST, GET, OPTIONS
    Content-Length: 8160
    Content-Type: text/html; charset=utf-8
    Date: Mon, 20 Nov 2017 18:56:35 GMT
    Server: WSGIServer/0.2 CPython/3.6.3
    Vary: Accept, Cookie
    X-Frame-Options: SAMEORIGIN
    
    
    
      
        
    
          
            
            
          
    
          Snippet List – Django REST framework
    
          
            
              
              
    ...
    
  • 과 유사하게 API
  • 에 다양한 유형의 데이터를 전송할 수 있습니다.
  • post form data
  • (django_rest_framework) [root@localhost django_rest_framework]# http --form POST http://127.0.0.1:80/snippets/ code="hello world post form data"
    HTTP/1.0 201 Created
    Allow: POST, GET, OPTIONS
    Content-Length: 110
    Content-Type: application/json
    Date: Mon, 20 Nov 2017 18:58:58 GMT
    Server: WSGIServer/0.2 CPython/3.6.3
    Vary: Accept, Cookie
    X-Frame-Options: SAMEORIGIN
    
    {
        "code": "hello world post form data",
        "id": 6,
        "language": "python",
        "linenos": false,
        "style": "friendly",
        "title": ""
    }
    
  • post json data
  • (django_rest_framework) [root@localhost django_rest_framework]# http --json POST http://127.0.0.1:80/snippets/ code="hello world post json data"
    HTTP/1.0 201 Created
    Allow: POST, GET, OPTIONS
    Content-Length: 110
    Content-Type: application/json
    Date: Mon, 20 Nov 2017 18:59:44 GMT
    Server: WSGIServer/0.2 CPython/3.6.3
    Vary: Accept, Cookie
    X-Frame-Options: SAMEORIGIN
    
    {
        "code": "hello world post json data",
        "id": 7,
        "language": "python",
        "linenos": false,
        "style": "friendly",
        "title": ""
    }
    
  • 요청 시 --debug 접미사를 추가하면 요청 상세 정보를 확인할 수 있습니다.
  • (django_rest_framework) [root@localhost django_rest_framework]# http --json POST http://127.0.0.1:80/snippets/ code="hello world post json data" --debug
    HTTPie 0.9.9
    Requests 2.18.4
    Pygments 2.2.0
    Python 3.6.3 (default, Nov  4 2017, 22:19:41) 
    [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
    /root/.pyenv/versions/3.6.3/envs/django_rest_framework/bin/python
    Linux 3.10.0-693.el7.x86_64
    
    ",
        "stderr_isatty": true,
        "stdin": "<_io.textiowrapper name="<stdin>" mode="r" encoding="UTF-8">",
        "stdin_encoding": "UTF-8",
        "stdin_isatty": true,
        "stdout": "<_io.textiowrapper name="<stdout>" mode="w" encoding="UTF-8">",
        "stdout_encoding": "UTF-8",
        "stdout_isatty": true
    }>
    
    >>> requests.request(**{
        "allow_redirects": false,
        "auth": "None",
        "cert": "None",
        "data": "{\"code\": \"hello world post json data\"}",
        "files": {},
        "headers": {
            "Accept": "application/json, */*",
            "Content-Type": "application/json",
            "User-Agent": "HTTPie/0.9.9"
        },
        "method": "post",
        "params": {},
        "proxies": {},
        "stream": true,
        "timeout": 30,
        "url": "http://127.0.0.1:80/snippets/",
        "verify": true
    })
    
    HTTP/1.0 201 Created
    Allow: POST, GET, OPTIONS
    Content-Length: 110
    Content-Type: application/json
    Date: Mon, 20 Nov 2017 19:00:45 GMT
    Server: WSGIServer/0.2 CPython/3.6.3
    Vary: Accept, Cookie
    X-Frame-Options: SAMEORIGIN
    
    {
        "code": "hello world post json data",
        "id": 9,
        "language": "python",
        "linenos": false,
        "style": "friendly",
        "title": ""
    }
    
  • 브라우저에서 요청
  • 브라우저에서 요청을 보내면 기본적으로 html 형식의 데이터
  • 을 되돌려줍니다
  • 은 이전처럼 url 접두사를 붙여서 json 데이터
  • 을 요청할 수 있습니다

    정보


    저는 Django REST 프레임워크를 처음 배웠습니다. Django REST 프레임워크 학습 기요 시리즈는 제가 홈페이지 문서에서 배운 초보적인 소화 성과입니다. 오류가 있으면 바로잡아 주십시오.
    학습용 코드 Github 창고:shelmingsong/djangorest_framework
    본 문서는 Tutorial 2: Requests and Responses

    블로그 업데이트 주소

  • 송명요의 블로그 [첫 번째 업데이트]
  • 칼럼Python Cookbook
  • 흐르는 달 0의 글
  • 좋은 웹페이지 즐겨찾기