본문 바로가기

Web Programming/Django

Portfolio 프로젝트 (Static 파일 처리)

Portfolio 프로젝트

다음과 같은 포트폴리오 형태의 웹을 만들고자 하는데 우리는 Django를 이용하여 여러 파일 다루어보고자 한다


Django에서 다룰 수 있는 파일은 정적파일, 동적파일 두 가지가 존재하는데


정적파일(static)은 미리 서버에 저장된 파일

동적파일(dynamic)은 서버의 데이터들이 어느정도 가공된 다음 제공되는 파일


그 중에서 이번엔 정적파일, Static 파일을 처리하는 방법을 학습한다


정적파일 종류

1) 프로젝트 입장에서 이미 뭔지 아는 파일(static)

2) 웹 서비스 이용자들이 업로드하는 파일(media)


Static 파일 처리과정

1. 위치 찾기

2. 한 곳에 모으기


우리가 할일

1. static 담을 폴더 만들기 (App/static 폴더 만들고 거기 넣기)

2. static 파일 어디있고 어디로 모을지 알려주기 (settings.py에서)

3. 모으기 ($ python manage.py collectstatic)

-> html 가서 static 파일 쓸거라고 명시 후 사용


실습 1. Static


먼저 portfolio app을 추가한다

그리고 app을 settings.py에 프로젝트에 연결시켜줘야 한다

그 후, portfoio app 안에 templates 폴더를 만들고 안에 portfolio.html을 추가한다


그 다음, view에 함수 작성


1
2
3
4
# app(portfolio)/views.py
 
def portfolio(request):
    return render(request, 'portfolio.html')
cs

 

urls.py에 url 작성


1
2
3
4
# urls.py
import portfolio.views
...
path('portfolio/', portfolio.views.portfolio, name='portfolio'),
cs


다음 settings.py에 다음의 코드를 추가한다


1
2
3
4
5
6
7
# settings.py
...
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'portfolio''static')
]
 
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
cs

STATICFLES_DIRS : static 파일들이 들어있는 경로를 적어준다.
STATIC_ROOT : django에서는 편의를 위해 흩어져있는 static파일을 한곳에 모으는데, 그때 파일을 모아줄 위치를 나타낸다.


그리고 다음의 명령어를 통해 static 파일들을 모아준다


1
$ python manage.py collectstatic
cs


그리고 이제 html 파일 내에서 static 파일을 불러오고자 한다면 다음의 코드를 한줄 추가한다


1
{% load staticfiles %}
cs


실제 이미지를 사용하고자 한다면 다음의 코드를 활용해서 static의 이미지 파일을 불러오면 된다

이때 이미지는 해당 app 폴더 내의 static 이라는 폴더를 추가해서 그곳에 이미지 파일을 담으면 된다


1
<img src="{% static '원하는 이미지.jpg' %}" alt="">
cs


실습 2. Media

Static 파일은 미리 준비해둔 파일 보여주는 것에 불과

Media 파일은 upload 후에 제공하는 것


즉, Media 파일은 외부와 통신을 통해 제공하는 것임

이 때 외부와의 통신을 위해 URL 사용


<처리 과정>

0) settings.py 설정

1) url.py 설정

2 (models.py에서 업로드 될 데이터 class 정의

3) DB에게 migrate

4) admin.py에 admin.site.register

5) 모든 객체 내용 보여주기 (views.py)

6) HTML 띄우기


먼저 Media 파일을 사용하기 위한 설정을 해준다


1
2
3
4
#settings.py
 
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
cs


그리고 Url에 static url을 추가해준다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# urls.py
 
from django.conf import settings
from django.conf.urls.static import static
...
 
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', blog.views.home, name='home'),
    path('blog/<int:blog_id>',blog.views.detail, name="detail"),
    path('blog/new/',blog.views.new,name="new"),
    path('blog/create/', blog.views.create, name='create'),
 
    path('portfolio/', portfolio.views.portfolio, name='portfolio'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
cs


그리고 이미지를 담을 모델 class를 작성해준다


1
2
3
4
5
6
7
8
9
# portfolio/models.py
 
class Portfolio(models.Model):
        title = models.CharField(max_length=255)
        image = models.ImageField(upload_to='images/')
        description = models.CharField(max_length=500)
    
        def __str__(self):
            return self.title
cs


그리고 이미지를 처리하기 위한 라이브러리인 pillow를 설치해줍니다(파이썬 이미지 라이브러리)

1
$ pip install Pillow
cs


그리고 모델을 migrate 해준다

1
2
$ python manage.py makemigrations
$ python manage.py migrate
cs


그리고 admin.py를 수정해서 admin에서 portfolio를 추가할 수 있도록 해준다


1
2
3
4
5
6
# portfolio/admin.py
 
from django.contrib import admin
from .models import Portfolio
 
admin.site.register(Portfolio)
cs


그리고 view 함수를 수정해준다


1
2
3
4
5
6
7
8
9
# portfolio/views.py
 
from django.shortcuts import render
 
from .models import Portfolio
 
def portfolio(request):
    portfolios = Portfolio.objects
    return render(request, 'portfolio/portfolio.html', {'portfolios': portfolios})
cs


마지막으로, template 파일도 수정을 해준다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# portfolio.html
...
<div class="album py-5 bg-light">
  <div class="container">
      <div class="row">
      {% for portfolio in portfolios.all %}
        <div class="col-md-4">
          <div class="card mb-4 shadow-sm">
            <img class="card-img-top" src="{{ portfolio.image.url }}" alt=" Card image cap">
            <div class="card-body">
              <h4>{{ portfolio.title }}</h4>
              <class="card-text">{{ portfolio.description }}</p>
            </div>
          </div>
        </div>
    {% endfor %}
    </div>
  </div>
</div>
cs