Django API TDD 삽질 여행기

Django API TDD 삽질 여행기

API TDD 이 요망한놈

API를 만들면서 많은 삽질이 있었지만 그중에서 가장 삽질을 많이했던 부분이 있다.

API로 image upload 테스트를 해볼라면 어떻게?

이 포스트는 이걸 나중에 까먹더라도 쉽게 찾아보기 위해 작성한다.

시나리오

일단, 클라이언트랑 JWT를 사용해서 통신을 한다는 가정하에 시나리오를 짜보자.

  1. setUp에서 signup, login을 해서 assertEqual, aseertTrue로 token값을 얻어낸다.
  2. test method를 만들고 test_data를 만들어준다. 이때 image는 media저장 경로에 있는걸 가지고 온다.
  3. HTTP_AUTHORIZATIONJWT값을 넣고 API 테스트
  4. assertEqual로 status_code랑 값 비교

대략 적인 시나리오를 이렇게 진행했다.

Demo Code

Demo Code를 보기전에 API로 Image를 테스트 할려고 하면 SimpleUploadedFile를 이용한다.

실제로 HTML Form에서 파일을 보낼때 request.FILES를 찍어보면 InMemoryUploadedFile로 넘어온다. 이렇게 HTML Form에서 보내는거 처럼 하기 위해서 SimpleUploadedFile를 사용하면 된다.

'Programming > Django' 카테고리의 다른 글

Django ImageField Upload를 AWS S3해보자  (0) 2016.07.15
honcho start using port  (0) 2016.07.07
JWT 설명 및 djangorestframework-jwt 사용법  (0) 2016.07.07
Django Study Summary  (0) 2016.07.02
Django development Setting  (0) 2016.05.24
블로그 이미지

LeoHeo

어제보다 더 나은 개발자가 되고자 합니다. LeoHeo - 허진한

,
Django ImageField Upload를 AWS S3해보자

Django ImageField Upload를 AWS S3해보자

이 포스팅에서는 Django에서 image를 자동으로 S3에 올리는 과정과 삽질했던 과정을 기록으로 남겨 나중에 쉽게 찾아보기 위해 작성한다. AWS S3, CloudFront에 대한설명은 따로 안할 예정이다.

같이 공부하면서 프로젝트를 진행하는데 Image 저장이라는 난제에 부딪쳤다.

  1. 이미지를 업로드하면 images/<year>/<month>/<day>/<username>/[username-year-month-day.extension]형식으로 저장이 되야 한다.
  2. 현재 https를 사용하기 때문에 https에 있는 저장장소를 사용한다.

그래서 image를 upload하면

위의 형식대로 S3에 자동으로 올라가면서 나중에 CloudFront로 쉽게 땡겨올수 있게 한다.

위 작업이 되기 위해서는 선행되어야 하는 작업이 있다.

  1. S3 Bucket이 존재해야한다.
  2. CloudFront Distributions을 해서 S3랑 연결되어있어야 한다.

CloudeFront의 경우 생성시 약 10분정도 기다려야 쓸 수 있기 때문에 미리 Distributions하고 작업을 할것을 권고한다.

ImageField Settings

일단 Django에서 imageField에 대해서 Documentation을 한번 살펴보자. Django ImageField Documentation

Django에 imageField는 FileField를 상속받아서 만들어졌다.

imageField같은 경우에는 upload_to라는 옵션을 이용해서 저장되는 장소를 지정할수가 있다.

uploadto를 사용하기 위해서는 MEDIAROOT, MEDIAURL이 세팅되어 있어야 한다.
아래부분에서 이 MEDIA
ROOT, MEDIA_URL을 AWS CloudFront주소로 세팅하는걸 알아보겠다.

upload_to라는 옵션에 대한 설명은 공식문서에 아주 잘되어 있다. upload_to documentation

위와같이 폴더 지정뿐만 아니라 %Y/%m/%d라는 값을 주면 uploads/2016/07/14라는 폴더로 upload가 된다.

이걸 보고 난 Wow!를 외치며 작업이 쉬워지는듯 했으나 내가 멍청해서인가 그건 또 아니였다......

그럼 맨처음 생각했던 Format에 대해서 다시한번 생각해보자.

images/<year>/<month>/<day>/<username>/[username-year-month-day.extension]

우리가 하고자 하는건 user라는 instance를 매번 새롭게 받아야 한다.

그래서 <username>/[username-year-month-day.extension]이렇게 되어야 한다.

django upload_to may also be a callable, such as a function

위의 공식문서에 보면 upload_to에 function를 쓰는 방법을 잘 설명해주고 있다.

upload_to에 functiontwo Arguments를 받고 Unix-style path (with forward slashes)를 사용한다고 한다.

그래서 우리가 할려고 했던 대로 코드를 짜면 아래와 같다.

user_directory_path라는 function이 우리가 생각했던 directory를 생성해주는 function이다.

set_filename_format은 filename을 우리가 지정한대로 바꿔주는 function으로 이름 중복 방지를 위해 microsecond를 붙였다.

그리고 os.path.splitext(filename)[1]를 이용하면 해당파일의 확장자를 가지고 올 수가 있다.

여기까지 하면 ImageField의 세팅은 끝이다.

django-storages-redux 사용 AWS S3 자동 업로드

django에서 https일 경우 staic file을 serving하는 방법은 내가 알기론 2가지 방법이 있다.

  1. ngix serving
  2. AWS S3 + CloudFront Serving

여기서는 2번째 방법에 대해서 알아보겠다.

2번째 방법을 하기 위해서 원래 django-storages라는걸 사용하면 AWS S3에 static file을 쉽게 업로드 할 수가 있다.

근데 이 django-storages가 중간에 한번 deprecated가 되었다..

그래서 github에서 찾아보면 django-storages, django-storages-redux 등등 많은 것들이 존재하는데 여기서는 django-storages-redux라는걸 사용해 보겠다.

공식 문서를 참고하기 바란다.

사용하기 위해서 가상환경에 2가지를 설치해줘야 한다.

  1. pip install boto

  2. pip install django-storages-redux

그러고 나서 설정해주어야 하는게 몇개 있다.
일단 DJANGO_SETTINGS_MODULEdevlopment, production으로 두개를 나누었다는 전제하에 설명을 진행하겠다.
그리고 production상태에서만 static file이 S3에 upload되게 하겠다.

  1. wsgi.py파일이 있는 경로에 storage.py 만들기
  2. 기존 production.py에 몇가지 설정 추가하기

storage.py파일 만들기

storage.py에 위와 같이 추가해준다.

production.py에 추가 할 것들

공식문서에 usage부분을 보면 일단 DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'를 설정하라고 한다.

그 다음에 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_STORAGE_BUCKET_NAME도 같이 설정해준다.

여기서 ACCESS_KEY, SECRET_ACCESS_KEY는 AWS에서 권장하기를 S3에 접근할 수 있는 I AM계정을 하나 만들어서 진행하는걸 추천한다.

root계정의 ACCESS_KEY, SECRET_ACCESS_KEY를 사용하지 말자.

그리고 우리는 CloudFront를 사용할것이기 때문에 AWS_S3_CUSTOM_DOMAIN, AWS_S3_CUSTOM_DOMAIN도 같이 추가 해준다.

최종적으로 production.py에 담겨야 하는 내용은 아래와 같다.

여기까지 했다면 다 설정을 한것이다.

실제로 작동 해보기

[django path]/manage.py collectstatic --setings="appname.settings.production"를 하면 S3로 업로드가 잘 작동할것이다.

발생하는 있는 에러들

ygulify 에러

ubuntu환경에 대해서 설명을 하겠다.

'Programming > Django' 카테고리의 다른 글

Django Image Upload API TDD 삽질 여행기  (0) 2016.07.24
honcho start using port  (0) 2016.07.07
JWT 설명 및 djangorestframework-jwt 사용법  (0) 2016.07.07
Django Study Summary  (0) 2016.07.02
Django development Setting  (0) 2016.05.24
블로그 이미지

LeoHeo

어제보다 더 나은 개발자가 되고자 합니다. LeoHeo - 허진한

,
블로그 이미지

LeoHeo

어제보다 더 나은 개발자가 되고자 합니다. LeoHeo - 허진한

,

'Programming > Django' 카테고리의 다른 글

Django Image Upload API TDD 삽질 여행기  (0) 2016.07.24
Django ImageField Upload를 AWS S3해보자  (0) 2016.07.15
honcho start using port  (0) 2016.07.07
Django Study Summary  (0) 2016.07.02
Django development Setting  (0) 2016.05.24
블로그 이미지

LeoHeo

어제보다 더 나은 개발자가 되고자 합니다. LeoHeo - 허진한

,
블로그 이미지

LeoHeo

어제보다 더 나은 개발자가 되고자 합니다. LeoHeo - 허진한

,

블로그 이미지

LeoHeo

어제보다 더 나은 개발자가 되고자 합니다. LeoHeo - 허진한

,