Lina's Toolbox

Django Static & Media 본문

스파르타 내일 배움 캠프 AI 웹개발 과정/Django framework

Django Static & Media

Woolina 2024. 9. 12. 02:30

Static Files

  • 정적 파일(멈춰있는 파일)을 의미합니다.
  • 서비스 로직에서 별도의 처리 없이 보여주기만 하면 되는 파일을 의미합니다.
    • 서비스 이미지 파일(로고, 광고 이미지 …)
    • 자바스크립트파일, CSS 파일 등
  • 이러한 서비스 로직과 다르게 그냥 무조건 주기만 하면 되는 파일들이기 때문에 모아서 따로 제공할 수 있습니다.

사용해보기

Django는 역시 다 준비되어있다.

 

정적인 데이터를 "보여준다"는 건 response인건데

response가 있다는건 request도 있어야한다는 것이다.

스태틱데이터가 request를 어떻게 한다는 걸까? → url로 요청한다. 

→ 이렇게 스태틱 파일들의 url을 설정해주는게 static_url

 

STATIC_URL

  • static 파일을 참조할 때 사용할 url입니다.
    • 개발 단계에서는 기본적으로 app/static 폴더 생성하여 넣거나,
      더 필요하다면 settings의 STATICFILES_DIRS 에 정의된 경로 참조
    • 실제 디렉토리 경로가 아님에 주의 ! URL로만 존재하는 경로입니다.

 

accounts, articles 여러 앱에서 다 공통적으로 적용되는 정적파일이 있다면?

  STATICFILES_DIRS  = [BASE_DIR/"static"] 해준것.

 이경로란 = > base directory안에 static이라는 폴더 새로 생성해준것

 

STATIC_ROOT

  • 배포를 위해 정적 파일을 수집하는 디렉토리의 절대경로
  • django 프로젝트에서 사용하는 모든 정적 파일을 이곳으로 모아서 적용
    • 단, DEBUG=True 인 경우 동작 X (개발 단계)
  • 추후 배포시 모든 정적파일을 다른 웹 서버가 직접 제공하기 위함

collectstatic

python manage.py collectstatic
  • STATIC_ROOT에 모든 정적 파일을 수집하는 명령어
  • 지금 말고 배포과정에서 사용
    이 명령어를 사용하면  settings.py에서 STATIC_ROOT = BASE_DIR/"staticfiles" 라면,
    프로젝트 디렉토리 아래 staticfiles라는 폴더 안에 모든 static파일들이 들어간다.

각 앱의 static 디렉토리

  • <app_name>/static/<app_name>
    햄버거처럼 article아래 static아래에도 articles만들어준다.
    이 경로에 이미지 파일을 아무거나 넣어보자!

템플릿에서 정적파일 사용하기

  • {% load static %}
  • {% static ‘file_path’ %}

진짜 사용해보기

  1. settings.py 설정 및 static 디렉토리 생성

 

 

2. articles/static/articles 생성하고 파일 넣기

 

3. index.html

{% load static %} → 나 이 템플릿에서 스태틱 사용할거야! 를 알려줌

alt = "" 이미지 로드 실패했을때 나올 글자를 적어주는 것. 필수가 아니므로 지워도됨.

 

여기까지 완료하고 접속해보면….

드디어 내 사이트에도 이미지가 !

 

  • 개발자도구를 열어서 이미지 태그의 경로를 확인해봅시다.

STATIC_URL의 의미

 

하는 김에 CSS도 적용해봅시다. 이미지 크기가 다소 큰 것 같네요.

BASE_DIR/static/css/style.css

img {
  width: 200px;
}

 

 

base.html

<link rel="stylesheet" href="{% static 'css/style.css' %}">

다른 앱에서도 쓸수 있게끔 공통 css를  만든것!

공통 static폴더에 바로 넣지말고, 깔끔하게 css폴더도 만들어주자.


Media Files

파일 업로드 기능을 구현해볼까요?

  • (우리서비스에 포함된 파일은 아니고) 유저가 웹에서 업로드한 모든 파일을 말합니다. (static file을 제외 모든 파일)

사용해보기

MEDIA_ROOT

  • 업로드한 파일이 저장되는 디렉토리 경로를 지정합니다.
  • 업로드 파일은 데이터베이스에 저장되지 않으며 실제 저장되는 것을 파일의 경로입니다.
    (곰돌이를 관리자도구에서 찍어보면 STATIC_URL/은  실제 파일경로 x  url 경로임을 알 수 있다.)

MADIA_URL

  • 미디어를 처리를 위한 URL

 

settings.py

배포단계에는 바로 접근하도록 바꿀거지만,

지금은 media/에 저장한다. 이건 개발모드(settings.py DEBUG = TRUE)일 때 사용하는 설정!!

 

개발단계에서는 에러났을때 내부코드, 파일경로  보여준다. → 이런 내부 정보가 실제 유저한테는 보이면 안될것!

DEBUG = FALSE 로 바꿔주고 hosts 켜서 다시 서버 실행하면 이제 에러페이지가 깔끔해진다! (ex. 404 error)

 

 

project app / urls

from django.conf import settings
from django.conf.urls.static import static

...
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

개발 단계에서 MEDIA 파일 사용하는 방법

 

if settings.DEBUG:

→ 지금 개발모드면 실행

→ MEDIA_URL인 애들은 (/media/~),  MEDIA_ROOT(폴더경로)을 보고 찾아 라는 뜻.

→ 이 세팅을 더해줘야지만 개발단계에서 media파일을 쓸 수 있게 된다.

 

 

글에 이미지를 삽입할 수 있게 해보자!

Artiles에 사진 필드 넣기

Image Field

  • Image Field는 이미지 업로드에 사용되는 모델 필드입니다.
✔️ 어떻게 사용하는 건지 공식문서를 한 번 찾아볼까요? https://docs.djangoproject.com/en/4.2/ref/models/fields/#imagefield

 

imageFiled는 FileField를 상속받아 만들어져있어,

기본적으로 FileField이지만 이미지인지 검사합니다.

파일필드: 모든 파일 올릴 수 있음

이미지파일: 이미지파일만 올릴 수 있다.

  • upload_to
    • 이미지가 업로드 되는 경로를 지정
    • MEDIA_ROOT의 하위 경로를 지정
  • 한 번 해봅시다!

imageField는 varchar가 저장되어있다! (이미지 파일의 경로를 저장)

데이터 변경되었으니 python manage.py makemigrations, migrate 해주자.

→ 데이터베이스에서 이미지 컬럼 생김

 

 

 

장고에서 이미지필드를 사용할때는 pillow 패키지가 필요하다!

pillow 설치

pip install pillow
pip freeze > requirements.txt

ImageField를 사용하기위해서는 pillow 라이브러리 설치가 필요합니다. 먼저 pillow를 설치해주세요.

💡 null 과  blank의 차이

blank
form에서 해당 값을 입력하지 않아도 괜찮다.


null
DB에 null을 저장해도 된다. 

이미지가 없는 글도 있을것이다. blank=True를 써줘야 이미지필드가 optional이 된다.

장고에서는 이미지 필드에는 null=true를 주지 않는 것을 권장한다. (이걸 지키지 않아도 에러는 나지 않음)

 

수정하기

  • 사진이 전송되지 않아! → 잘 보내주고 잘 받아야함

create.html 변경하기

{% extends "base.html" %}


{% block content %}
<h1>New Article</h1>

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

 

  • form의 enctype 속성
    • form의 데이터 전송 형식을 지정하는 것으로 기본적으로는 텍스트 형식의 데이터 교환이 이루어집니다.
    • multipart/form-data
      • 전송 형식을 지정하는 것으로 file, image 전송시 사용합니다.
      • <input>type=file 사용시 application/x-www-form-urlencoded 가 기본값입니다.
  • articles/views.py 변경하기
@login_required
def create(request):
    if request.method == "POST":
        form = ArticleForm(request.POST, request.FILES)
        if form.is_valid():
            article = form.save()
            return redirect("articles:article_detail", article.id)
    else:
        form = ArticleForm()

    context = {"form": form}
    return render(request, "articles/create.html", context)

뷰에서 받을때도 변경해줘야한다.

files = request.FILES (클라이언트 쪽에서 넘어온 파일들 다 여기 들어있다.)

 

우리는 지금 모델 폼을 쓰고 있으니 이 과정은 굳이 안해도는 된다.

궁금하다면, ArticleForm을 타고 BaseModelForm 코드를 보자

인자 self, data, file순! 

두번째 인자로 request.FILES가 들어가는 이유 👀

 

 

media/아래 images폴더가 생성되고 그 아래 저장됨

우리가 \-> images/아래 저장하라고 설정해줬기 때문에

media/아래 images폴더가 생성되고 그 아래 저장되었다.

 

Article에 사진 넣기

article_detail.html

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

image가 있는 article인 경우에 이미지 출력

 

근데 이미지 없는 글을 눌러보면 에러가 난다. (image.url를 찾을 수 없으므로)

→ if 로 처리

 

 

파일을 업로드 할 때, 파일 미리보기 기능을 만들고 싶다면 자바스크립트로 처리한다.


runserver의 비밀

  • 우리가 사용하는 runserver 는 ‘개발용’ 서버를 실행하는 것입니다. (엄연히 말하면 웹서버가 아님.)
  • 순수 python으로 작성되었으며 django에 포함되어있어 개발을 편하게 도와주는 역할을 합니다.
  • 절대로 개발 서버를 운영 환경에서 사용해서는 안됩니다!
    • 만약 python manage.py runserver를 이용해서 배포한다면 문제가 생깁니다.
    • 동시 접속 20개의 연결 정도면 펑! 하고 서버가 터질 수 있습니다.
  • Django는 Web Framework이며 실제 운영시에는 웹 서버를 앞쪽에 달아줘야함
  • 관련 내용은 추후 배포에서 다룰 예정이니 지금은 django framework에 집중!