정적 파일(static files) & 미디어 파일(media files)

210725, 210726

정적파일 관리하기 - 포스트 목록 페이지에 부트스트랩 적용하기

예전에 1, 2강에서 사용했던 부트스트랩을 사용하려고 한다. 이를 불러온다. 위치는 blog/static/blog/bootstrap 안에 css 파일들을 모두 불러오면 된다.

그리고 예전에 사용한 blog_list.html 을 모두 복사해서 지금 가지고 있는 post_list.html 로 붙여넣는다.

이 때 서버를 실행하면 부트스트랩이 적용이 되지 않는다. 이유는 올바른 부트스트랩 경로를 참조하고 있지 않기 때문. 일단 장고에서는 무조건 urls.py를 통해 경로 접근이 가능해야 한다. 근데 여기서 static 파일들을 바로 접근할 수 있도록 하는 코드가 있다. 바로 이것.

<!DOCTYPE html>
{% load static %}
<html>
<head>
    <title>상만두의 웹사이트</title>
    <link href="{%  static 'blog/bootstrap/bootstrap.min.css' %}" rel="stylesheet" type="text/css">
    <script src="https://kit.fontawesome.com/726bbd6862.js" crossorigin="anonymous"></script>
</head>

{% load static %} 을 써주면 된다. 그리고 이후에 css 파일을 참조할 때 6번 줄과 같이 써주면 된다.

내 게시글 수 만큼 Blog Post를 반복하게 하려면 다음과 같이 for문을 써서 동적으로 만들어 주면 된다. 이 때 포스트 제목과 내용, 연결 링크까지 수정해주자.

{% for p in post_list %}
<!-- Blog post-->
<div class="card mb-4">
    <a href="#!"><img class="card-img-top" src="https://dummyimage.com/700x350/dee2e6/6c757d.jpg" alt="..." /></a>
        <div class="card-body">
        <div class="small text-muted">January 1, 2021</div>
        <h2 class="card-title h4">{{ p.title }}</h2>
        <p class="card-text">{{ p.content }}</p>
        <a class="btn btn-primary" href="{{ p.get_absolute_url }}">Read more →</a>
    </div>
</div>
{% endfor %}

그리고, created_at 을 추가해주자. 또, 추후에 models.py 를 수정해서 author 까지 추가해줘야 하는데 까먹지 말라고 명시해두자

<div class="card-footer text-muted">
    Posted on {{ p.created_at }} by
    <a href="#">작성자명 쓸 위치</a>
</div>

정적파일 관리하기 - 블로그 포스트 상세 페이지에 부트스트랩 적용하기

블로그 포스트 디자인도 부트스트랩을 적용하려고 한다.

  • 현재는 5.0 버전이고 강의는 4.5.3 버전. 이 링크는 4.6버전이다.

여기서 index.html 의 코드를 다운받고 post_detail.html 에 붙여넣기. 그리고 models.py 에 정의되어 있는 데이터들로 좀 바꿔준다. title, created_at, context 등등

네비게이션 바 클래스로 fixed-top 이 있는데, 스크롤을 내리더라도 네비게이션 바가 상단에 유지되게 하는 기능이다. 이 때 body에 있는 내용이 네비게이션바에 가려질 수가 있기 때문에 다음과 같이 추가해야 한다.

blog_post.css

body {
    padding-top: 56px;
}

당연히 이 css 파일을 불러오려면 static 으로 불러와야 한다

post_detail.html

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

미디어 파일 관리하기 - 이미지 파일 업로드를 위한 ImageField

기본적으로 static 파일들은 장고가 접근할 수 있도록 프로젝트 폴더의 settings.pySTATIC_URL 에 정의되어 있다. 사진이나 동영상 같은 미디어 파일들도 접근할 수 있도록 MEDIA_URL 에 정의하자.

settings.py

import os

BASE_DIR = Path(__file__).resolve().parent.parent

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, '_media')
  • 기본적으로 BASE_DIR이 정의되어있고 미디어 파일을 관리하는 폴더를 BASE_DIR 하위 디렉토리에 두기 위해서 os 라이브러리를 호출하고 연결한다.

또한, 프로젝트 폴더의 urls,py 에서 한번 더 수정해줘야 한다

urls.py

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

urlpatterns = [
    path('blog/', include('blog.urls')),
    path('admin/', admin.site.urls),
    path('', include('single_pages.urls'))
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
  • 이 때 document_root 를 설정해주지 않으면 C드라이브 하위 디렉토리 _media 폴더를 찾게된다. 꼭 MEDIA_ROOT 로 설정해줄 것.

또, 이미지를 추가하기 위해 models.py 를 수정한다.

blog/models.py

class Post(models.Model):
    head_image = models.ImageField(upload_to='blog/images/%Y/%m/%d/')
  • 년/월/일/ 폴더에 저장할 것이다.

  • 장고에서는 ImageField 타입도 제공한다.

    • 이 때 Pillow를 설치해야 한다. 파이썬에서 이미지를 다룰 수 있게 해주는 패키지

  • black=True는 다음과 같이 빈칸으로 두었을 때 에러메시지가 나오는 것을 사라지게 해준다.

    • 기본값은 False 기 때문에 제목이나 내용을 빈칸으로 둘 수 없었다.

  • 이 때 model의 데이터가 바뀌는 것이므로 python manage.py makemigrationspython manage.py migrate를 꼭 해주자.

이 때 이미지를 추가해주면,

미디어 파일들을 관리하는 폴더가 알아서 생긴 모습

이 때 폴더 관리를 위처럼 하는 이유가 있다. 만약 이미지 이름이 2021-07-26-줌배경.jpg 였다면, 모든 파일들의 이름을 체크해야 하는 번거로움이 있다. 디렉토리 구조를 다음과 같이 나눠놓으면 이미지 탐색시간이 훨씬 줄어들게 된다.

그리고, post_list.html 에서도 이 이미지를 출력할 수 있게 수정해준다

<a href="#!"><img class="card-img-top" src="{{ p.head_img.url }}" alt="{{ p.title }}" /></a>
  • 이 때 리로드를 하면 오류가 난다.

    • 왜냐하면 세번째 포스트에만 이미지가 있고 두번째, 첫번째 포스트에는 이미지가 없기 때문

    • 원래는 if 문으로 처리해야 한다.

      • 이는 나중에 다룰 것

모든 포스트에 이미지를 업로드해주면 정상적으로 로딩이 되는 모습

이 때 업로드 한 파일이 같으면 자동으로 다른 이름으로 저장해준다.

깃에서 media 파일까지 관리할 필요없게 ignore에 미디어 폴더를 추가한다. 아직 post_detail.html 에 있는 이미지는 바뀌지 않았다. 따라서 이것도 수정해준다.

<img class="card-img-top img-fluid rounded" src="{{ post.head_image.url }}" alt="{{ post.title }}"/>

미디어 파일 관리하기 - 파일 업로드를 위한 FileField

이번에는, 파일을 업로드 해보자.

models.py

class Post(models.Model):
    file_upload = models.FileField(upload_to='blog/files/%Y/%m/%d/', blank=True)

파일 업로드 기능이 추가된 모습(migrate 필수)

이 때, post_detail.html 에도 업로드 된 파일을 출력해주거나 다운받을 수 있는 기능을 제공하도록 코드를 작성해줄 수 있다. 이것은 이후에 if문을 배운 뒤 해볼 것.

Last updated

Was this helpful?