본문 바로가기
  • 실행력이 모든걸 결정한다
Django

[Django] 정적 파일 및 미디어 파일 처리

by 김코더 김주역 2021. 8. 9.
반응형

1. static 파일 처리

Django의 웹페이지에 css를 적용하거나 이미지를 추가할 때는 일반적인 파일 경로로 불러와서는 안된다.

왜냐하면 기본적으로 Django에 들어오는 요청은 모두 Controller에서 가로채기 때문인데, settings.py의 STATIC_URL 항목을 통해 정적 파일을 먼저 확인할 수 있게 해야 한다.

즉, settings.py 파일에 다음과 같이 설정되어 있으면 된다.

STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

html 파일은 templates 디렉토리에 따로 빼두었듯이, css, javascript, 이미지 파일같은 정적 파일들은 settings.py의 STATICFILES_DIRS 항목에 지정한 디렉토리에 저장해주면 된다.

 

템플릿 코드에서는 {% load static %} 키워드로 static 디렉토리를 가져오면 되고, 정적 파일 경로는 settings.py의 STATIC_URL 항목에 지정한 경로와 {% static %} 태그로 지정한 경로를 합쳐서 생성된다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'users/red.css'%}">
</head>
<body>
    <p>red text!</p>
    <img src="{% static 'users/img/pad.PNG'%}" width="500px">
</body>
</html>

 

실행 결과

참고로, {% static %} 태그의 인자로는 위의 예시와 같이 문자열을 줄 수도 있지만 아래의 예시처럼 변수로 주는 방법도 있다는 점을 참고해두자. 예를 들어, URL을 템플릿 변수에 저장하려면 다음과 같이 사용하면 된다.

{% static 'users/img/pad.PNG' as padimg %}
...
<img src="{{ padimg }}"></img>

 

 

 

2. staticfiles 애플리케이션

INSTALLED_APPS = [
    ...
    'django.contrib.staticfiles',
    ...
]

 

1) staticfiles 애플리케이션이란?

- 개발 환경용 웹 서버인 runserver가 정적 파일을 처리할 때 사용하는 애플리케이션이다. staticfiles 애플리케이션은 개발 환경에서 사용되며, DEBUG 모드가 True인 경우에만 활성화된다.

 

 

2) 동작 과정

요청 URL이 settings.py의 STATIC_URL 항목에 지정한 경로로 시작하면 staticfiles 앱의 views.serve() 메소드를 호출하면서 STATIC_URL 부분을 제외한 요청 URL를 메소드의 인자로 전달한다. views.serve() 메소드는 settings.py의 STATICFILES_FINDERS 항목에 지정된 파인터를 이용하여 정적 파일(또는 미디어 파일)을 검색한다. 디폴트 설정은 global_settings.py에 지정되어 있다. 

# django/conf/global_settings.py

STATICFILES_FINDERS = [
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
    # 'django.contrib.staticfiles.finders.DefaultStorageFinder',
]

FileSystemFinder는 STATICFILES_DIRS 항목에 지정된 디렉토리들을 검색하고, AppDirectoriesFinder는 INSTALLED_APPS 항목에 등록된 앱들을 순서대로 순회하면서 각 앱의 static 디렉토리를 검색한다. INSTALLED_APPS 항목에 FileSystemFinder가 앞에 지정되어 있기 때문에 FileSystemFinder가 먼저 동작하며, 동일한 이름의 정적 파일을 여러 개 발견했다면 처음으로 찾은 파일을 사용한다.

주석 처리 해놓은 DefaultStorageFinder은 DEFAULT_FILE_STORAGE 설정 항목으로 지정된 디렉토리를 검색한다.

파인더에 의해 정적 파일을 찾았다면 runserver은 찾은 파일을 브라우저에 응답하고, 찾지 못했다면 404 Not Found 에러 응답을 브라우저로 보낸다.

 

 

3) staticfiles 애플리케이션을 위한 settings.py 설정 항목

(1) STATIC_ROOT

- 배포 과정에서 실행하는 collectstatic 명령은 정적 파일들을 찾아서 STATIC_ROOT 디렉토리에 복사한다. 상용 웹 서버는 정적 파일들을 서비스하기 위해 이 디렉토리를 찾는다.

- 기본값은 None이다.

 

(2) STATIC_URL

- 정적 파일로 간주하기 위한 URL prefix를 지정한다.

- 기본값은 None이다.

 

(3) STATICFILES_DIRS

- 주로 프로젝트에 공통인 정적 파일들을 모아두는 곳이다. FileSystemFinder는 STATICFILES_DIRS 항목에 지정된 디렉토리들을 검색하여 정적 파일을 찾는다.

- 리스트 또는 튜플로 지정한다.

- 기본값은 빈 리스트([])다.

 

(4) STATICFILES_STORAGE

- collectstatic 명령으로 정적 파일을 모을 때 사용하는 파일 저장소 엔진용 클래스를 지정한다.

- 기본값은 'django.contrib.staticfiles.storage.StaticFilesStorage'다. StaticFilesStorage는 STATIC_ROOT 항목으로 지정된 디렉토리에 정적 파일을 모아준다.

- 상용 모드에서는 AWS S3같은 별도의 저장소를 사용한다.

 

(5) STATICFILES_FINDERS

- 정적 파일을 찾아주는 파인더 클래스들을 지정한다.

- 기본값은 [2) 동작 과정]에서 설명했다.

 

 

 

3. media 파일 처리

- media 파일은 사용자가 업로드한 파일을 의미한다.

- settings.py 설정 방법은 정적 파일 설정과 유사하다. 단, STATIC_ROOT와 같은 값을 가지면 에러가 발생한다는 점에 유의하자.

MEDIA_URL='/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

- 모델 클래스에도 미디어 파일을 위한 필드들이 있다. 이미지를 다루는 models.ImageField와 비디오 등의 각종 파일을 다루기 위한 models.FileField가 존재한다.

# 출처 : https://stackoverflow.com/questions/56969479/adding-video-field-in-django

img = models.ImageField(upload_to='images_uploaded',null=True)
video = models.FileField(upload_to='videos_uploaded',null=True,
    validators=[FileExtensionValidator(allowed_extensions=['MOV','avi','mp4','webm','mkv'])])

위에 있는 upload_to 속성은 미디어 파일이 저장될 디렉토리를 의미하며, 이 디렉토리는 /media/ 하위에 생성된다.

- runserver 서버는 media 파일을 자동으로 가져와주지 않기 때문에, 직접 urls.py에 URL 패턴을 추가해줘야 한다.

# urls.py

urlpatterns = [
    ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

이렇게 해두면, MEDIA_URL로 들어오는 요청에 대해 MEDIA_ROOT 경로를 탐색하게 된다.

 

 

+ 추가 개념)

- STATIC_ROOT : 정적 파일의 배포 및 서비스를 위한 임시 저장소

- STATICFILES_DIRS 또는 각 앱의 static 디렉토리 : 정적 파일에 대한 영구 저장소

- MEDIA_ROOT : 미디어 파일에 대한 영구 저장소

 

반응형

댓글