반응형

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 ... %} 는 정적 파일의 실제 URL을 (STATIC_URL 설정에 따라) 자동으로 생성한다.
현재 STATIC_URL'static/'으로 설정되있으므로, 아래와 같이 변환된다.
  • {% 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 개발 서버가 요청을 받은 시점에 탐색 시작.

탐색 프로세스

  1. 브라우저가 정적파일의 URL로 정적 파일을 요청.
  2. Django 개발 서버가 요청 수신.
  3. staticfiles 앱이 다음 순서로 실시간 탐색:
    • STATICFILES_DIRS에 지정된 경로들 확인.
    • INSTALLED_APPS의 각 앱의 static 폴더 확인.
  4. 파일을 찾으면 해당 파일 제공, 못 찾으면 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'

탐색 프로세스

  1. collectstatic 실행 시:
    • STATICFILES_DIRS 경로들 탐색.
    • INSTALLED_APPS의 각 앱의 static 폴더 탐색.
    • 발견된 모든 정적 파일을 STATIC_ROOT 디렉토리로 복사.
  2. 서비스 운영 중:
    • 브라우저가 정적 파일을 요청.
    • .웹 서버(Nginx, Apache 등)가 STATIC_ROOT 디렉토리에서 직접 파일 제공
      • 웹 서버가 /static/으로 시작하는  URL을 감지하고, 웹서버의 설정에 따라 특정 디렉토리(Django에서 STATIC_ROOT로 명시한 곳과 같은 디렉토리) 내부에서 파일을 찾고, 직접 클라이언트에 전송.
    • Django는 이 과정에 관여하지 않음
      • 따라서 Django 서버의 부하를 줄일 수 있음.
      • 웹서버는 정적 파일 서빙에 더 최적화 되어있으므로 서빙이 Django보다 더 빠름.
      • 필요하다면, 웹서버에서 정적파일을 캐싱할 수도 있음.

만약 정적 파일을 외부 서버에 두고 싶으면?

만약 정적 파일을 AWS S3, CloudFront, CDN, 혹은 다른 외부 서버에 올리고 싶다면:

  • STATIC_ROOT는 일단 로컬 경로로 지정해두고, 
  • collectstatic 명령어를 이용해서 로컬에 모은 다음,
  • 그걸 외부 서버로 업로드하는 추가 작업을 해야한다.
    • 예: django-storages 라이브러리를 사용해서 S3에 바로 업로드하도록 설정할 수 있다.

 

정적 파일 관리의 장점

  1. 개발/배포 환경 분리 (동일한 코드로 동작)
    • 개발 환경에서는 Django의 개발 서버가 정적 파일을 직접 제공
    • 배포 환경에서는 웹 서버나 CDN이 정적 파일을 제공
  2. 유연한 파일 경로 관리
    • STATIC_URL 설정만 변경하면 모든 정적 파일의 경로가 자동으로 업데이트
    • 파일 위치가 변경되어도 템플릿 코드를 수정할 필요가 없음
  3. 성능 최적화
    • 캐싱과 버전 관리를 위한 파일 핑거프린팅 지원
    • collectstatic 명령어를 통한 효율적인 정적 파일 관리

 

마무리

Django의 정적 파일 관리 시스템은 개발자가 효율적으로 정적 리소스를 관리할 수 있게 해준다.특히 {% static %} 템플릿 태그를 통해 유연하고 유지보수가 쉬운 방식으로 정적 파일을 참조할 수 있다. 이는 프로젝트가 커지고 복잡해져도 정적 파일 관리를 일관되게 유지할 수 있게 해주는 큰 장점이다.

반응형

+ Recent posts