ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Django Rest Framework 의 APITestCase 에서 API 를 요청할 때 Body 데이터를 보내는 두가지 방법
    기술/Django 2021. 9. 24. 20:17

    APITestCase 에서 POST, PATCH, PUT 을 사용하여 데이터를 보낼 때는 보내는 데이터가 multipart 가 아니면 반드시 content_type 을 지정해주어야 합니다.

    이 때 내부 동작을 살펴보며 왜 기본이 multipart 가 선택되는지, 다른 두가지 방법은 어떻게 동작하는지에 대해 설명합니다.

    APITestCase 에서 API 를 요청하는 두가지 방법

    rest framework 에서 API 를 테스트를 할 때는 APITestCase 를 상속받아 client 를 통해 아래와같이 호출하게 됩니다.

    self.client.post(revese('post-list'), data=data)

    이 때 self.client  rest_framework.test.APIClient 의 인스턴스 입니다.

    APIClient 의 안쪽을 분석해보며 데이터를 어떻게 전송해야할지 설명합니다.

    기본 동작

    rest_framework.test._encode_data 에서 content_type 을 결정하고 데이터를 전송 가능한 스트림형태로 바꿉니다.

    content_type  settings.TEST_REQUEST_DEFAULT_FORMAT 에 정의되어 있는 값, multipart 를 기본으로 채택합니다.

    {
     "key": "value",
     "key2": {
       "nested-key": "value"
     }
    }

    Multipart 는 위와 같은 형태의 Dictionary 가 주어지면 아래와 같은 형태로 request.data 에 도착하게 됩니다.

    즉, request.data.get("key2").get("nested-key") 를 했을 때 값을 가져올 수 없게 됩니다.

    {
      "key": "value",
      "key2": "\{\"nested-key\": \"value\"\}"
    }

    그래서 Multipart 형태가 아닌 JSON 형태로 보내서 Netsed 한 데이터를 제대로 참조할 수 있게 해야합니다.

    1. content_type

    self.client.post(revese('post-list'), data=json.dumps(data), content_type='application/json')

    content_type 을 제공하는 경우 반드시 django.utils.encoding.force_bytes 를 통과할 수 있는 형태로 보내야합니다.

    • bytes
    • None, int, float, Decimal, datetime.datetime, datetime.date, datetime.time
    • memoryview
    • str() 메서드를 사용가능한 형태

    만약 데이터가 force_bytes 로 처리할 수 없는 경우는 처리 가능한 형태로 바꿔 전달해야합니다.

    2. format

    좀 더 데이터를 간단히 처리할 수 있는 format 을 사용하는 방법입니다.

    self.client.post(revese('post-list'), data=data, format='json')

    지원되는 포맷은 settings.TEST_REQUEST_RENDERER_CLASSES 에 정의되어 있는 값들입니다.

    기본적으로 json, multipart 형태의 전송을 지원합니다.

    format 을 지정하면 해당 문자열에 해당하는 renderer_class  render 메서드를 통해 데이터를 전송 가능한 형태로 변경합니다.

    요약

    1. content_type, format 두개가 지정되지 않은 경우 기본 multipart 형태입니다.
    2. content_type 을 지정하고 데이터를 미리 직렬화해서 보냅니다.
    3. format 을 지정하고 데이터를 직렬화하지 않고 보냅니다.

    댓글

Designed by Tistory.