앞에서는 글을 쓰는 블로그 게시판을 구현했다. 이번에는 사진을 보여주는 포트폴리오 페이지를 만들어 보자.
새로운 app 만들기
이번엔 Django를 이용해 여러 파일들을 다뤄보는 연습도 해보자.
app 만들기
python manage.py startapp portfolio
Bash
복사
앱을 만들고 settings.py에 app을 등록해준다.
template 만들기
view 만들기
URLconf
이렇게 하고 서버를 테스트해본다.
template 수정하기
bootstrap의 album에서 가져온 소스코드를 복붙한다.
필요없는거 지우고 지우고 단어 몇 개 바꾸면 위와 같은 페이지가 나온다.
Portfolio app 만들기
admin에서 사진과 간단한 설명을 입력하면 위의 형식에 맞춰 페이지를 띄우도록 해볼 예정이다.
Static file
로컬에서 사진을 올리기 위해 static file에 대해 짚고 넘어가야한다. static 파일을 번역하면 정적 파일이라고 할 수 있는데, 앞서 static web페이지를 만들때 사용했던 CSS, JS, image 같은 것들이라 생각하면 된다.
Djnago는 파일을 2가지로 구분한다.
•
static - 웹서비스를 위해, 개발자가 준비해두는 파일
•
media - 웹서비스 이용자들이 업로드하는 파일
먼저 static 파일을 이용하여 portfolio 파일에 사진을 첨부해 보자.
portfolio 폴더 안에 static 폴더를 만들어준다. 그리고 그 폴더 안에 portfolio 화면에 띄우고 싶은 사진 한장을 넣어보자.
그리고 settings.py로 가서 아래 코드를 추가해준다.
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'portfolio', 'static')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Python
복사
•
STATICFLES_DIRS : static 파일들이 들어있는 경로를 적어준다.
•
STATIC_ROOT : django에서는 편의를 위해 흩어져있는 static파일을 한곳에 모으는데, 그때 파일을 모아줄 위치를 나타낸다.
위의 작업까지가 static 폴더를 만들고 우리 django 프로젝트에게 static 폴더라는게 생겼다는걸 알려주는 작업이었다. 그리고 터미널로 가서 static 파일들을 한곳에 모아주는 명령어를 입력한다.
python manage.py collectstatic
Bash
복사
모두 잘 만들었으면, 다음과 같이 blogproject의 하위 폴더에 static 폴더가 생긴다.
그럼 이제 template로 가서 static 폴더에 있는 mario를 띄워보자.
template에서 static폴더 안에 있는 파일들을 불러오기 위해서는 template에 static파일을 불러오겠다는 문구를 추가해줘야한다.
{% load staticfiles %}
HTML
복사
portfolio.html 파일안의 main 태그 위에 넣어준다.
이제 img 태그를 추가해보자. src만 신경써서 적어주면 된다.
<img src="{% static 'siba.jpg' %}" alt="">
HTML
복사
이런식으로 적어주면,
이런 페이지가 나온다.
이번엔 static이 아니라 media 파일을 활용해보자.
settings.py에 media 설정하기
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = 'media/'
Python
복사
URLconf
from django.contrib import admin
from django.urls import path
import blog.views
import portfolio.views
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)
Python
복사
settings와 static 관련 내용을 import하고 맨 마지막에 static 관련한 한줄을 추가해준다.
model 만들기
이번에 모델에서 받아올 정보는 이미지 파일과 텍스트 파일이다.
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
Python
복사
앞서 만들었던 blog app의 model과 다른 점이 있다면 이미지를 업로드 한다는 점이다. 그래서 image를 살펴보면 upload_to='images/'라는 내용이 있는데 이부분이 업로드된 이미지들을 images 폴더안에 넣으라는 의미이다.
위와 같이 모델 구성이 끝났으면 migration을 할 차례이다.
python manage.py makemigration
Bash
복사
python manage.py migrate
Bash
복사
순서대로 코드를 작성해주고, 경고창이 뜨며 Pillow가 작성되지 않았다고 하는 경우 설치해준다.
pip install Pillow
Bash
복사
django admin에게 새로운 모델이 생겼다는걸 알려줘야 한다.
blog app에서 작성했던걸 복붙해 온다. blog 폴더 안에 admin.py안에 있는 내용을 복사해, portfolio 안 admin.py안에 붙여넣고, blog라고 쓰여진 내용을 전부 portfolio로 바꿔보자.
from django.contrib import admin
from .models import Portfolio
# Register your models here.
admin.site.register(Portfolio)
Python
복사
저장 후 admin 페이지를 확인해보자.
들어온 김에 글을 하나 써보자
view 수정하기
from django.shortcuts import render
from .models import Portfolio
# Create your views here.
def portfolio(request):
portfolios = Portfolio.objects
return render(request, 'portfolio/portfolio.html', {'portfolios': portfolios})
Python
복사
template 수정하기
<div class="album py-5 bg-light">
<div class="container">
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
{% for portfolio in portfolios.all %}
<div class="col">
<div class="card shadow-sm">
<img src="{{ portfolio.image.url }}" alt="">
<div class="card-body">
<h4>{{ portfolio.title }} </h4>
<p class="card-text">{{ portfolio.description }}</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary">View</button>
<button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
</div>
<small class="text-muted">9 mins</small>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
HTML
복사
이런식으로 template까지 수정하면,
이렇게 잘 나온다.
정리해보면,
1.
settings.py에 media파일이 어떤 url을 타고 프로젝트로 들어올지, 어디로 모아줄지 정의한다.
2.
urls.py에 이미지가 타고 들어올 url을 설계해준다.
3.
업로드 하고싶은 데이터 class를 models.py에 정의해준다.
4.
이미지 업로드를 위한 pillow 모듈설치 후 DB가 알아들을 수 있도록 migration,migrate해준다.
5.
admin.py에 ‘portfolio DB사용할거야’ 하고 알려준다. 이제 admin페이지에 portfolio가 나타난다.
6.
views.py에서 모든 객체를 받아 HTML로 넘겨준다.
7.
HTML에 나의 포트폴리오가 보여지게 된다.
이것저것
포트폴리오 작성할때도 매번 admin 들어가기 귀찮아서 포트폴리오용 글쓰기 페이지를 만들었다.
수많은 오류와의 사투 끝에 결국 해냄
먼저 이런식으로 view를 구성한다. 제목, 설명, 날짜, 사진첨부 기능이 필요하니까. request.POST.get() 메소드를 사용해봤다. 기존 request.GET[]으로 사전형으로 만드는 것 보다 뒤에 .get하나씩 붙이니까 코드를 짤때도 더 직관적이고 좋았다.
근데 이전에 만든 blog와 이름이 겹쳐서 자꾸 헷갈리고 오류가 뜨더라.. 그래서 이름을 모두 pf(portfolio)를 추가해서 수정했다.
URL도 설정해주고
그렇게 만들어진 writepf.html POST 메소드를 쓸때는 csrf_token을 사용해야한다. 오류방지용.