-
[Django] static 파일언어/파이썬 & 장고 2017. 1. 26. 17:19
Django 정적 파일
Django는 실 서비스 환경에서 사용할 정적 파일을 제공하는 기능을 제공하지 않습니다. 서버에 저장된 정적 파일을 읽어들여서 그대로 웹 클라이언트에 보내기만 하면 그만인 단순한 기능인데도 Django는 그런 기능을 제공하지 않습니다. 왜냐하면 그럴 필요가 없기 때문인데, 앞서 설명한 바와 같이 그런 작업에 대해서는 웹 서버가 전문가이기 때문입니다.
게다가 웹 애플리케이션은 웹 서버와 연결하는 중간 인터페이스를 거치므로 효율이 더 떨어집니다. 하지만, 개발 상황인 경우는 효율보다는 기능(역할)이 중요한 경우가 많습니다. 정적 파일이 제대로 제공되는지 확인하려고 항상 웹 서버를 구동할 필요는 없습니다. Django는 개발 단계에서 쓸 정적 파일 제공 기능을 제공합니다. 성능은 웹 서버가 직접 정적 파일을 제공하는 것 보다 떨어지지만 정적 파일 제공에 필요한 기능은 대부분 지원합니다.
Django은 정적 파일을 크게 Static file과 Media file 두 종류로 구분합니다.
Static file은 Javascript, CSS, Image 파일처럼 웹 서비스에서 사용하려고 미리 준비해 놓은 정적 파일입니다. 파일 자체가 고정되어 있고, 서비스 중에도 수시로 추가되거나 변경되지 않고 고정되어 있습니다.
Media file은 이용자가 웹에서 올리는(upload) 파일입니다. 파일 자체는 고정되어 이지만, 언제 어떤 파일이 정적 파일로 제공되고 준비되는지 예측할 수 없습니다.
Static file과 Media file은 정적 파일이라는 점에서는 같지만, 정적 파일을 제공하는 상황을 예측할 수 있는지 여부는 다릅니다. Static file은 서비스에 필요한 정적 파일을 미리 준비해놓기 때문에
manage.py
도구에findstatic
과collectstatic
이라는 기능으로 정적 파일을 모으고 찾는 관리 기능을 제공합니다.manage.py
은 Django 프로젝트를 관리하는 일에 필요한 기능을 명령줄 쉘(shell)에서 수행하는 도구입니다. 그에 반해 Media file은 이용자가 웹에서 올리는 파일이므로 미리 예측해서 준비할 수 없습니다. 그래서 Static file 관련된 관리 기능인findstatic
과collectstatic
기능을 사용하지 못합니다.Static file
Static file은 웹 서비스에 사용할 정적 파일을 미리 준비하여 제공하는 데 사용합니다. Django로 운영되는 프로젝트의 설정을 관리하는
settings.py
에 Static file와 관련된 항목이 다섯 가지 존재하며, 보통은 다음 세 가지를 사용합니다.- STATICFILES_DIRS
- STATIC_URL
- STATIC_ROOT
STATICFILES_DIRS
STATICFILES_DIRS
은 개발 단계에서 사용하는 정적 파일이 위치한 경로들을 지정하는 설정 항목입니다. 특정 Django App(Django로 생성한 프로젝트를 Django 프로젝트라 하고, Django 프로젝트는 뭔가를 수행하는 기능 단위인 Django App을 모아놓은 좀 더 큰 단위입니다.) 에만 사용하는 정적 파일이 있거나 혹은 정적 파일을 관리하기 용이하게 하기 위해 여러 경로(path)에 정적 파일을 배치하였다면, 이 경로들을 Python의list
나tuple
로 담으면 됩니다.STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )
대개는
static
이라는 디렉터리에 정적 파일을 담습니다. 주의할 점은 정적 디렉터리 경로가 하나이더라도 반드시list
나tuple
로 담아야 한다는 점입니다.manage.py
에서 제공하는 명령어 중findstatic
은STATICFILES_DIRS
에 설정한 경로에서 지정한 정적 파일을 찾습니다.STATIC_URL
STATIC_URL
은 웹 페이지에서 사용할 정적 파일의 최상위 URL 경로입니다. 이 최상위 경로 자체는 실제 파일이나 디렉터리가 아니며, URL로만 존재하는 단위입니다. 그래서 이용자 마음대로 정해도 상관없습니다.STATIC_URL = '/assets/'
문자열은 반드시
/
로 끝나야 합니다.findstatic
명령어로 탐색되는 정적 파일 경로에STATIC_URL
경로를 합치면 실제 웹에서 접근 가능한 URL이 됩니다.STATIC_URL
은 정적 파일이 실제 위치한 경로를 참조하며, 이 실제 경로는STATICFILES_DIRS
설정 항목에 지정된 경로가 아닌STATIC_ROOT
설정 항목에 지정된 경로입니다.STATIC_ROOT
STATIC_ROOT
는 Django 프로젝트에서 사용하는 모든 정적 파일을 한 곳에 모아넣는 경로입니다. 한 곳에 모으는 기능은manage.py
파일의collectstatic
명령어로 수행합니다. Django가 모든 파일을 검사하여 정적 파일로 사용하는지 여부를 확인한 뒤 모으는 건 아니고, 각 Django 앱 디렉터리에 있는static
디렉터리와STATICFILES_DIRS
에 지정된 경로에 있는 모든 파일을 모읍니다.개발 과정에선, 정확히는
settings.py
의DEBUG
가True
로 설정되어 있으면STATIC_ROOT
설정은 작용하지 않으며,STATIC_ROOT
는 실 서비스 환경을 위한 설정 항목입니다. 그래서 개발 과정에선STATIC_ROOT
에 지정한 경로가 실제로 존재하지 않거나 아예STATIC_ROOT
설정 항목 자체가 없어도 문제없이 동작합니다. 실 서비스 환경에서STATIC_ROOT
이 필요한 이유는 이 경로에 있는 모든 파일을 웹 서버가 직접 제공(serving)하기 위함입니다. 아래 예제를 통해 확인해 보겠습니다.settings.py
에 다음과 같이STATIC_ROOT
설정 항목을 추가합니다.STATIC_ROOT = os.path.join(BASE_DIR, 'collected_statics')
list
나tuple
형인STATICFILES_DIRS
와는 달리 문자열 경로를 할당합니다. 이제collectstatic
명령어로 현 프로젝트가 사용하는 모든 정적 파일을 모읍니다.$ python manage.py collectstatic
지정한 경로에 있는 기존 파일을 전부 덮어 쓰는데 정말로 모을 거냐고 묻습니다. 원본 파일을 덮어 쓰는 게 아니니
yes
라고 입력합니다. 정적 파일을 모을 경로를manage.py
파일이 있는 경로에collected_statics
디렉터리로 지정했으므로 이 디렉터리가 만들어지고, 이 안에 사용하는 모든 정적 파일이 복사됩니다.이렇게 정적 파일을 모아놓은
STATIC_ROOT
는 Django가 직접 접근하진 않습니다. Django가 접근하여 다루는 설정은STATICFILES_DIRS
이며,STATIC_ROOT
는 정적 파일을 직접 제공(serving)할 웹 서버가 접근합니다.collectstatic
명령어를 수행하면STATICFILES_DIRS
나 앱 디렉토리에 있는static
디렉토리 안에 있는 파일을STATIC_ROOT
에 모으는데,STATICFILES_DIRS
에 지정된 경로인 경우 따로 명시한 접두사으로 디렉토리를 만들어 그 안에 파일을 복사하고, 앱 디렉토리에 있는static
디렉토리인 경우는 앱 이름으로 디렉토리를 만들어 그 안에static
디렉터리 안에 있는 파일을 복사합니다. 즉, 개발 단계(DEBUG = True
)에서는 정적 파일 URL 경로가 논리 개념이고, 서비스 환경(DEBUG = False
)에서는 실제 물리 개념인 정적 파일 URL 경로가 되는 것입니다.주의할 점은
STATIC_ROOT
경로는STATICFILES_DIRS
등록된 경로와 같은 경로가 있어서는 안 됩니다. 남들이 잘 안 쓸만한 이상한 이름(collected_statics
?)을 쓰는 것을 추천합니다.Media file
Media file은 이용자가 웹에서 업로드한 정적 파일입니다. 미리 준비해놓고 제공하는 Static file과는 달리 언제 어떤 파일이 추가될 지 모르므로
findstatic
과collectstatic
같은 명령어는 Media file에 대해서는 무의미합니다.settings.py
에 Media file와 관련된 항목이 두 가지 존재합니다.- MEDIA_ROOT
- MEDIA_URL
파일 업로드와 관련하여 세부 조정하는 설정이 몇 가지 더 있지만, 대개는 기본 설정(
global_settings
)대로 써도 무방합니다.MEDIA_ROOT
는 이름이STATIC_ROOT
과 비슷한데, 업로드가 끝난 파일을 배치할 최상위 경로를 지정하는 설정 항목입니다.STATIC_ROOT
보다는STATICFILES_DIRS
이 더 비슷한 역할을 합니다. 또한MEDIA_ROOT
는STATIC_ROOT
와 다른 경로를 지정해야 합니다.MEDIA_URL
은STATIC_URL
과 이름도 비슷하고 역할도 비슷합니다./
로 끝나는 URL 경로 문자열로 설정해야 한다는 점도 같습니다.MEDIA_URL
도MEDIA_ROOT
와 마찬가지로STATIC_URL
과 URL 경로가 달라야 합니다. 아래 예제를 통해 더 자세히 설명하겠습니다.먼저
settings.py
에서MEDIA_ROOT
부분을 작성한 예제입니다.MEDIA_URL = '/uploads/' MEDIA_ROOT = os.path.join(BASE_DIR, 'uploaded_files')