장고 프로젝트 중 사용자가 등록한 이미지를 데이터베이스에 저장하고 가져다 써야할 경우가 있다.
다른 일반 값들은 {% csrf_token %}이 있으면 그냥 저장하고 가져다 쓰면 되지만 이미지 파일은 특정 디렉토리에 어버로드하고 이 디렉토리에 접근할 수 있는 경우 보안상의 위험이 존재할 수 있다.
따라서 장고는 기본적으로 'MEDIA_ROOT'와 'MEDIA_URL' 설정을 사용하여 이미지 파일을 안전하게 저장하고 쓸 수 있게 모든 기능들을 제공한다.
STATIC_URL = 'static/'
MEDIA_URL = "media/"
MEDIA_ROOT = BASE_DIR / "media" # 프로젝트 디렉토디에 'media'폴더가 생성되어 모든 이미지 파일은 그곳에 저장되어 관리한다.
from django.contrib import admin
from django.urls import include, path
from . import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path(...),
...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
장고의 static()
함수는 정적 파일
(ex. 이미지, css, javascript 등)의 URL
을 생성하고 이 파일들을 웹 어플리케이션 서버로 제공한다.
이 함수를 사용하면 템플릿에서 정적 파일의 경로를 동적으로 생성할 수 있다. 즉, 이 정적 파일의 경로를 통해서 웹 어플리케이션이 사진 업로드 같은 작업을 할 수 있다.
static()
함수는, Django의 django.contrib.staticfiles.views.serve 뷰 함수
를 호출하여 정적 파일(static files)을 제공하기 위해 사용된다.
이 함수는 두 가지 필수 인자를 받는데,
첫 번째 인자
로 정적 파일의 URL경로를 받고, 일반적으로 settings.py의 'STATIC_URL' 설정에 해당한다.
두 번쨰 인자
로는 실제로 정적 파일이 저장된 디렉토리의 경로를 받고, 일반적으로 settings.py에 정의된 'document_root' 설정에 해당한다.
탬플릿의 img 태그에는 아래와 같이 경로를 나타낸다.
<img src="/media/{{request.user.image}}" onerror="this.style.display='none'">
사용자가 제공한 이미지는,
탬플릿의 form태그를 통해 서버에 전달되는데, 이미지 파일은 다른 일반 문자열 데이터와는 다르게 비교적 거대한 크기의 데이터이기 때문에 인코딩 타입을 설정해줘야 한다.
<form action="" method="post" enctype="multipart/form-data">
<div>
<label>프로필 이미지</label>
<input type="file" name="image" />
</div>
</form>
실제 데이터베이스에는 아래와 같은 형식으로 가져와서 저장한다.
image = request.FILES.get('image')
# image = 데이터베이스의 모델 데이터의 이미지 값이 들어갈 필드
# get()함수 안의 'image' = 탬플릿의 input태그의 'name' 값 (사용자 입력값)
값을 넣어준다 혹은 덮어씌운다고 보면 될 것 같다.
만약, 이미지를 넣고 Post요청을 했는데 media 폴더에 파일 생성이 되지 않는다면 인코딩 타입을 지정해줬는지 한 번쯤은 확인해볼 가치가 있다고 생각된다.