Django 프로젝트를 개발시 CSS, JavaScript, 이미지와 같은 정적 파일들을 관리해야 할 필요가 있다. Django는 이러한 정적 파일들을 효율적으로 관리할 수 있는 시스템을 제공한다. Django의 정적 파일 관리 방법에 대해 정리해봤다.
자세한 내용은 공식문서를 확인하자 : https://docs.djangoproject.com/en/5.1/ref/settings/#std-setting-STATIC_URL
Settings | Django documentation
The web framework for perfectionists with deadlines.
docs.djangoproject.com
기본 설정하기
먼저 프로젝트 설정(config) 디렉토리의 settings.py에서 정적 파일 관련 설정을 해야 한다:
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]
- STATIC_URL: 웹 URL에서 정적 파일을 참조할 때 사용할 기본 URL prefix이다.
- STATIC_URL의 목적은 템플릿에서 "정적 파일 URL의 접두어 문자열 설정", 즉 정적파일의 URL 생성이다.
- 예를 들어 http://example.com/static/css/style.css와 같이 "static/"이 URL의 일부가 된다.
- 배포 환경에서는 웹서버(nginx, apache 등)이 /static/에 대한 요청이 올 때 어떤 디렉터리에서 파일을 서빙할지 웹서버의 설정파일에 개발자가 명시해야 한다.
- STATICFILES_DIRS: Django가 정적 파일을 찾아볼 추가 디렉토리 목록을 지정한다.
- 위 설정은 "프로젝트 루트의 static 폴더에서도 정적 파일을 찾아보라"는 의미이다.
- STATICFILES_DIRS는 주로 프로젝트 단위 공통 static 파일을 관리하려고 지정한다.
- 배포시에 collectstatic이 STATICFILES_DIRS까지 참고해서 정적 파일을 모으나, 실제 서비스에서는 웹서버(Nginx 등)들이 STATICFILES_DIRS가 아닌 STATIC_ROOT만 바라본다.
템플릿에서 정적 파일 사용하기
템플릿에서 정적 파일을 사용하려면 두 가지 단계가 필요하다:
1. 템플릿 최상단에 static 템플릿 태그를 로드한다:
{% load static %}
{% load static %} 탬플릿 태그는, static 템플릿 태그를 사용 가능하게 함으로써 CSS, JavaScript, 이미지 등의 정적 파일을 템플릿에서 사용할 수 있게 해준다.
2. static 템플릿 태그를 사용하여 정적 파일을 참조한다:
<!DOCTYPE html>
<html>
<head>
<title>My Site</title>
<link rel="stylesheet" href="{% static 'css/main.css' %}">
</head>
<body>
<img src="{% static 'images/logo.jpg' %}" alt="Logo">
<script src="{% static 'js/app.js' %}"></script>
</body>
</html>
- {% static 'css/main.css' %} → '/static/css/main.css'
- {% static 'images/logo.jpg' %} → '/static/images/logo.jpg'
- {% static 'js/app.js' %} → '/static/js/app.js'
참고로, STATIC_URL이 상대경로일 때, SCRIPT_NAME이라는 값이 설정되있지 않다면, '/'가 prefix된다. 그래서 STATIC_URL이 'static/'이어도 '/static/...'으로 변환되는 것이다.
# 일반적인 경우
STATIC_URL = 'static/'
결과: '/static/css/style.css' # SCRIPT_NAME 없을 때 '/'가 붙음
# 서브 경로에서 실행되는 경우
SCRIPT_NAME = '/myapp'
STATIC_URL = 'static/'
결과: '/myapp/static/css/style.css'
{% static ... %} 태그가 해석되는 시점은, Django가 템플릿을 렌더링할 때이다. 구체적인 과정을 살펴보면,
1. 브라우저가 페이지 요청
2. Django 뷰 함수 실행
3. 템플릿 렌더링 시작
4. {% static 'css/main.css' %} 발견
5. STATIC_URL + 파일경로로 변환
예: 'static/' + 'css/main.css' -> 'static/css/main.css'
6. 변환된 URL이 포함된 HTML을 브라우저에 전송
프로젝트 구조
일반적인 Django 프로젝트의 정적 파일 구조는 다음과 같다:
my_project/
├── manage.py
├── my_project/
│ ├── settings.py
│ └── urls.py
├── static/ # 프로젝트 레벨 정적 파일
│ ├── css/
│ ├── js/
│ └── images/
└── my_app/
└── static/ # 앱 레벨 정적 파일
정적 파일 탐색
{% static 'css/style.css' %}
위와 같은 탬플릿 파일의 {% static ... %} 태그는 URL을 생성하는 역할을 수행한다.
브라우저는 해당 URL이 적힌 html 파일을 수신한다. 그리고 이 URL로 요청을 보낸다.
요청을 받을 때, Django 서버가 현재 개발 환경인지, 아니면 운영 환경인지에 따라 대응 로직이 다르다:
1. 개발 환경(DEBUG=True) 일 때
파일 탐색 시점
- 브라우저가 정적 파일 URL을 요청할 때마다 실시간으로 탐색.
- Django 개발 서버가 요청을 받은 시점에 탐색 시작.
탐색 프로세스
- 브라우저가 정적파일의 URL로 정적 파일을 요청.
- Django 개발 서버가 요청 수신.
- staticfiles 앱이 다음 순서로 실시간 탐색:
- STATICFILES_DIRS에 지정된 경로들 확인.
- INSTALLED_APPS의 각 앱의 static 폴더 확인.
- 파일을 찾으면 해당 파일 제공, 못 찾으면 404 반환.
(URL 경로의 파일이 양쪽 위치에 모두 있다면, STATICFILES_DIRS에 있는 파일이 우선적으로 사용된다.)
위에 언급했듯, 정적 파일을 탐색하는 주체는 staticfiles 앱(django.contrib.staticfiles)이다.
정리하자면, Django의 개발 서버는 직접 정적 파일 요청이 들어올 때 때마다 실시간으로 파일을 찾아서 제공한다.
2. 운영 환경(DEBUG=False) 일 때
파일 탐색 시점
- 배포 전 python manage.py collectstatic 실행 시 한 번만 수행.
- 실제 서비스 중에는 탐색 과정 없음.
python manage.py collectstatic
- 배포를 위해 모든 정적 파일을 한 곳으로 수집할 때 실행하는 명령이다.
- STATIC_ROOT 디렉토리로 파일들을 복사한다.
- STATIC_ROOT는 Django가 실행 중인 서버의 로컬 디렉터리이다.
- 즉 운영 환경(배포)에서는 STATIC_ROOT를 settings.py에 미리 설정해둬야 한다.
STATIC_ROOT = BASE_DIR / 'staticfiles'
탐색 프로세스
- collectstatic 실행 시:
- STATICFILES_DIRS 경로들 탐색.
- INSTALLED_APPS의 각 앱의 static 폴더 탐색.
- 발견된 모든 정적 파일을 STATIC_ROOT 디렉토리로 복사.
- 서비스 운영 중:
- 브라우저가 정적 파일을 요청.
- .웹 서버(Nginx, Apache 등)가 STATIC_ROOT 디렉토리에서 직접 파일 제공
- 웹 서버가 /static/으로 시작하는 URL을 감지하고, 웹서버의 설정에 따라 특정 디렉토리(Django에서 STATIC_ROOT로 명시한 곳과 같은 디렉토리) 내부에서 파일을 찾고, 직접 클라이언트에 전송.
- Django는 이 과정에 관여하지 않음
- 따라서 Django 서버의 부하를 줄일 수 있음.
- 웹서버는 정적 파일 서빙에 더 최적화 되어있으므로 서빙이 Django보다 더 빠름.
- 필요하다면, 웹서버에서 정적파일을 캐싱할 수도 있음.
만약 정적 파일을 외부 서버에 두고 싶으면?
만약 정적 파일을 AWS S3, CloudFront, CDN, 혹은 다른 외부 서버에 올리고 싶다면:
- STATIC_ROOT는 일단 로컬 경로로 지정해두고,
- collectstatic 명령어를 이용해서 로컬에 모은 다음,
- 그걸 외부 서버로 업로드하는 추가 작업을 해야한다.
- 예: django-storages 라이브러리를 사용해서 S3에 바로 업로드하도록 설정할 수 있다.
정적 파일 관리의 장점
- 개발/배포 환경 분리 (동일한 코드로 동작)
- 개발 환경에서는 Django의 개발 서버가 정적 파일을 직접 제공
- 배포 환경에서는 웹 서버나 CDN이 정적 파일을 제공
- 유연한 파일 경로 관리
- STATIC_URL 설정만 변경하면 모든 정적 파일의 경로가 자동으로 업데이트
- 파일 위치가 변경되어도 템플릿 코드를 수정할 필요가 없음
- 성능 최적화
- 캐싱과 버전 관리를 위한 파일 핑거프린팅 지원
- collectstatic 명령어를 통한 효율적인 정적 파일 관리
마무리
Django의 정적 파일 관리 시스템은 개발자가 효율적으로 정적 리소스를 관리할 수 있게 해준다.특히 {% static %} 템플릿 태그를 통해 유연하고 유지보수가 쉬운 방식으로 정적 파일을 참조할 수 있다. 이는 프로젝트가 커지고 복잡해져도 정적 파일 관리를 일관되게 유지할 수 있게 해주는 큰 장점이다.
'Django' 카테고리의 다른 글
[Django] 사용자 모델 구현 방법 비교 (0) | 2025.01.22 |
---|---|
[Django] View 클래스의 as_view() 메서드 (0) | 2025.01.20 |
[Django] urlpatterns의 작동 원리 (0) | 2024.12.29 |
[Django] reverse 함수 (0) | 2024.12.28 |
[django] Model attribute들은 어떤 class attribute일까? (0) | 2023.11.23 |