[Django] Static File / Media File

문지은·2023년 4월 26일
0

Django 기초

목록 보기
9/14
post-thumbnail

정적 파일

  • HTML을 제외하고 웹 페이지를 렌더링 할 때 필요한 추가적인 파일을 의미한다.
  • 서버의 데이터들이 어느정도 가공된 후 보여지는 동적파일과 달리, 서버에 미리 저장되어 있어야하며, 서버에 저장된 그대로를 서비스한다.
  • 장고에서 정적파일은 아래의 두가지 파일로 분류될 수 있다.

Static File

  • 응답할 때 별도의 처리 없이 파일 내용을 그대로 보여주면 되는 파일
    • 사용자의 요청에 따라 내용이 바뀌는 것이 아니라 요청한 것을 그대로 보여주는 파일
  • 파일 자체가 고정되어 있고, 서비스 중에도 추가되거나 변경되지 않고 고정되어 있음
    • 예를 들어, 웹사이트는 일반적으로 이미지, 자바 스크립트 또는 CSS와 같은 미리 준비된 추가 파일(움직이지 않는)을 제공해야 함
  • Django에서는 이러한 파일들을 “static file”이라 함
    • Django는 staticfiles 앱을 통해 정적 파일과 관련된 기능을 제공

Media File

  • 미디어 파일
  • 사용자가 웹에서 업로드하는 정적 파일(user-uploaded)
  • 유저가 업로드 한 모든 정적 파일
  • 파일 자체는 고정되어 있지만 언제 어떤 파일이 제공될 지는 예측할 수 없음

⭐ Static files 구성하기

Django에서 정적 파일을 구성하고 사용하기 위한 몇가지 단계

  1. INSTALLED_APPSdjnago.contrib.staticfiles가 포함되어 있는지 확인하기
  2. settings.py 에서 STATIC_URL을 정의하기
# settings.py

INSTALLED_APPS = [
    'articles',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

...

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    BASE_DIR / 'static',
]
  1. 앱의 static 폴더에 정적 파일 위치 하기
    • ex) my_app/static/sample_img.jpg
  2. 템플릿에서 static 템플릿 태그를 사용하여 지정된 경로에 있는 정적 파일의 URL 만들기
{% load static %}

<img src="{% static 'sample.jpg' %}" alt="sample image" height="350">

Django template tag

{% load %}

  • load tag
  • 특정 라이브러리, 패키지에 등록된 모든 템플릿 태그와 필터 로드

{% static '' %}

  • static tag
  • STATIC_ROOT에 저장된 정적 파일에 연결

Static files 관련 Core Settings

STATIC_ROOT

  • Default : None
  • Django 프로젝터에서 사용하는 모든 정적 파일을 한 곳에 모아 넣는 경로
  • collectstatic이 배포를 위해 정적 파일을 수집하는 디렉토리의 절대 경로
  • 개발 과정에서 settings.py의 DEBUG 값이 True로 설정되어 있으면 해당 값은 적용되지 않음
  • 실 서비스 환경(배포 환경)에서 Django의 모든 정적 파일을 다른 웹 서버가 직접 제공하기 위해 사용
  • 배포 환경에서는 Django를 직접 실행하는 것이 아니라, 다른 서버에 의해 실행되기 때문에 실행되는 다른 서버는 Django에 내장되어 있는 정적 파일들을 인식하지 못함 (내장되어 있는 정적 파일들을 밖으로 꺼내는 이유)

[참고] collectstatic

  • STATIC_ROOT에 Django 프로젝트의 모든 정적 파일을 수집
# settings.py

STATIC_ROOT = BASE_DIR / 'staticfiles'
$ python manage.py collectstatic

STATICFILES_DIRS

  • Default : [] (empty list)
  • app/static/ 디렉토리 경로를 사용하는 것(기본 경로) 외에 추가적인 정적 파일 경로 목록을 정의하는 리스트
  • 추가 파일 디렉토리에 대한 전체 경로를 포함하는 문자열 목록으로 작성되어야 함
# 작성 예시

STATICFILES_DIRS = [
    BASE_DIR / 'static',
]

STATIC_URL

  • Default : None
  • STATIC_ROOT에 있는 정적 파일을 참조 할 때 사용할 URL
  • 개발 단계에서는 실제 정적 파일들이 저장되어 있는 app/static/ 경로(기본경로) 및 STATICFILES_DIR에 정의된 추가 경로들을 탐색
  • 실제 파일이나 디렉토리가 아니며, URL로만 존재
  • 비어 있지 않은 값으로 설정한다면 반드시 slash(/)으로 끝나야 함
# 작성 예시

STATIC_URL = '/static/'

⭐ Static files 사용하기

방법 1 - 기본 경로에 있는 static file 가져오기

  1. articles/static/articles 경로에 이미지 파일 배치하기

  2. static tag를 사용해 이미지 파일 출력하기

{% load static %}

<img src="{% static 'articles/sample_img_1.png' %}" alt="sample-image-1">

방법 2 - 추가 경로에 있는 static file 가져오기

  1. 추가 경로 작성
# settings.py

STATICFILES_DIRS = [
    BASE_DIR / 'static',
]
  1. static/ 경로에 이미지 파일 배치하기

  1. static tag를 사용해 이미지 파일 출력하기
{% load static %}

<img src="{% static 'sample_img_2.png' %}" alt="sample-image-2">

STATIC_URL 확인하기

  • Django가 해당 이미지를 클라이언트에게 응답하기 위해 만든 image url 확인하기
    • 개발자 도구 - inspect 버튼을 통해 확인
  • STATIC_URL + static file 경로 로 설정됨

⭐ Media Files

ImageField()

  • 이미지 업로드에 사용되는 모델 필드
  • FileField를 상속받는 서브 클래스이기 때문에 FileField의 모든 속성 및 메서드를 사용 가능
  • 더해서 사용자에 의해 업로드 된 객체가 유효한 이미지인지 검사
  • ImageField 인스턴스는 최대 길이가 100자인 문자열로 DB에 생성되며, max_length 인자를 사용하여 최대 길이를 변경할 수 있음

FileField()

  • FileField(upload_to=’’, storage=None, max_length=100, **options)
  • 파일 업로드에 사용하는 모델 필드
  • 2개의 선택 인자를 가지고 있음
    1. upload_to
    2. storage

FileField / ImageField 를 사용하기 위한 단계

  1. settings.py에 MEDIA_ROOT, MEDIA_URL 설정
  2. upload_to 속성을 정의하여 업로드된 파일에 사용할 MEDIA_ROOT의 하위 경로를 지정 (선택사항)

MEDIA_ROOT

  • Default : ’’ (Empty string)
  • 사용자가 업로드 한 파일(미디어 파일)들을 보관할 디렉토리의 절대 경로
  • Django는 성능을 위해 업로드한 파일은 데이터베이스에 저장하지 않음
    • 데이터베이스에 저장 되는 것은 파일 경로
  • MEDIA_ROOTSTATIC_ROOT와 반드시 다른 경로로 지정해야 함
# settings.py

# media
MEDIA_ROOT = BASE_DIR / 'media'

MEDIA_URL

  • Default : ’’ (Empty string)
  • MEDIA_ROOT에서 제공되는 미디어 파일을 처리하는 URL
  • 업로드 된 파일의 주소(URL)를 만들어 주는 역할
    • 웹 서버가 사용자가 사용하는 public URL
  • 비어 있지 않은 값으로 설정한다면 반드시 slash(/)로 끝나야 함
  • MEDIA_URL은 STATIC_URL과 반드시 다른 경로로 지정해야 함
# settings.py

# media
MEDIA_URL = '/media/'

개발 단계에서 사용자가 업로드한 미디어 파일 제공하기

  • 사용자로부터 업로드 된 파일이 프로젝트에 업로드 되고나서, 실제로 사용자에게 제공하기 위해서는 업로드된 파일의 URL 필요
    • 업로드 된 파일의 URL == settings.MEDIA_URL
    • 위 URL을 통해 참조하는 파일의 실제 위치 == settings.MEDIA_ROOT
# crud/urls.py

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('articles/', include('articles.urls')),
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)

⭐ Media File 사용하기

CREATE

ImageField 작성

  • 기존 컬럼 사이에 작성해도 실제 테이블에 추가 될 때는 가장 우측(뒤)에 추가됨
# articles/models.py

from django.db import models

# Create your models here.
class Article(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()
    # ImageField 작성
    image = models.ImageField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

Model field option (1) - blank

  • Defalut : False
  • True인 경우 필드를 비워 둘 수 있음
    • 이럴 경우 DB에는 ‘’(빈 문자열) 저장
  • 유효성 검사에서 사용 됨(is_valid)
    • “Validation-related”
    • 필드에 blank=True 가 있으면 form 유효성 검사에서 빈 값을 입력받을 수 있음

Model field option (2) - null

  • Defalut : False
  • True 인 경우 Django는 빈 값을 DB에 NULL로 저장함
    • “Database-related”
  • 주의사항 : ChartField, TextField와 같은 문자열 기빈 필드에는 null 옵션 사용을 피해야 함
    • 문자열 기반 필드에 null=True로 설정 시 데이터 없음에 대한 표현에 “빈 문자열”과 “NULL” 2가지 모두 가능하게 됨
    • “데이터 없음”에 대한 표현에 두 개의 가능한 값을 갖는 것은 좋지 않음
    • Django는 문자열 기반 필드에서 NULL이 아닌 빈 문자열을 사용하는 것이 규칙

Migrations

  • ImageField를 사용하려면 반드시 Pillow 라이브러리가 필요
    • Pillow 설치 없이는 makemigrations 실행 불가
$ pip install pillow
    
$ python manage.py makemigrations
$ python manage.py migrate
    
$ pip freeze > requirements.txt
  • Pillow
    • 광범위한 파일 형식 지원, 효율적이고 강력한 이미지 처리 기능을 제공하는 라이브러리
    • 이미지 처리 도구를 위한 견고한 기반 제공

enctype 속성 변경

  • 파일 또는 이미지 업로드 시에는 form 태그에 enctype 속성을 다음과 같이 변경해야 함.
<!-- article/create.hmtl -->

{% extends 'base.html' %}

{% block content %}
  <h1>글작성</h1>
  <hr>

  <form action="{% url 'articles:create' %}" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{form.as_p}}
    <input type="submit">
  </form>

{% endblock content %}

request.FILES

  • 파일 및 이미지는 request의 POST 속성 값으로 넘어가지 않고 FILES 속성 값에 담겨 넘어감
# articles/views.py

def create(request):
    if request.method == 'POST':
        form = ArticleForm(request.POST, request.FILES)
	...

이미지 첨부하기

  • 이미지를 첨부하지 않으면 blank=True 속성으로 인해 빈 문자열 저장
  • 이미지를 첨부한 경우는 MEDIA_ROOT 경로에 이미지가 업로드 됨
  • 파일 자체가 아닌 경로가 저장된다는 것 잊지 말 것!!!
  • 만약 같은 이름의 파일을 업로드 한다면 Django는 파일 이름 끝에 임의의 난수 값을 붙여 저장함.

READ

업로드 이미지 출력하기

  • 업로드 된 파일의 상대 URL은 Django가 제공하는 url 속성을 통해 얻을 수 있음
    • article.image.url - 업로드 파일의 경로
    • article.image - 업로드 파일의 파일 이름
<!-- article/detail.hmtl -->

<img src="{{article.image.url}}">
  • 이미지를 업로드 하지 않은 게시물을 detail 템플릿을 출력할 수 없는 문제 해결
    • 이미지 데이터가 있는 경우에만 이미지 출력할 수 있도록 처리
<!-- article/detail.hmtl -->

{% if article.image %}
  <img src="{{article.image.url}}">
{% endif %}

UPDATE

업로드 이미지 수정하기

  • enctype 속성 값 추가
<!-- article/update.hmtl -->

{% extends 'base.html' %}

{% block content %}
  <h1>글수정</h1>
  <hr>

  <form action="{% url 'articles:update' article.pk %}" enctype="multipart/form-data" method="POST">
...
  • 이미지 파일이 담겨 있는 request.FILES 추가 작성
# articles/views.py

def update(request, pk):
    article = Article.objects.get(pk=pk)
    if request.method == 'POST':
        form = ArticleForm(request.POST, request.FILES, instance=article)
profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

0개의 댓글