Media
프로젝트로 업로드 되는 파일
=> settings.py 에서 directory path, URL 을 지정해줘야 한다!
갑자기 URL? static에서는 없었는데..?
Static vs Media
Static 은 결국, 내 서버에 파일이 있는 경우를 의미하고,
Media는 남의 파일을 받아서 보여주는 것을 의미한다.
그렇다면 Static은 그냥 내가 저장해놓은 파일을 불러서 보여주면 되지만,
Media는 사용자가 업로드한 녀석을 내 서버에 받아두고, 이걸 다시 보여줘야 한다.
그렇다면 통신에 관련되서라면 URL이 빠질 수가 없다,,
왜? URL을 기반으로 우리는 통신하니까!
우리가 해야할 일
- 파일이 어떤 URL 을 타고 들어올 것인지
- 그리고 그 파일들을 어디에 모아서 관리할 것인지
이걸 settings.py에서 관리해주면 되겠다.
이렇게 정의를 했다면, 드디어 우리의 프로젝트한테 media 파일이 어떤식으로 들어올거야!
그리고 나중에 너가 이렇게 모아줘! 라고 말해준 격이다.
그러면 이제 이녀석도 알아먹었기 때문에
- 우리는
urls.py
에 가서 경로를 정해주고, - 그 url을 타고 들어오는 media 데이터를 어떻게 model 안에 넣어줄 것인지
models.py
에서 클래스를 정의하고, - DB한테 이런 친구 들어온다~ 하고 migration을 해서 또 프로젝트한테 알려주고,
- 우리는
/admin
에서 데이터를 집어 넣을 거니까,admin.py
에admin.site.register
를 해서 알려주고 - 이 데이터를 처리해서 보여주세요! 라는 정보처리에 관련된
views.py
에 함수도 정의를 해줘야 한다. - 그리고 HTML을 띄우면 끝!
실습
media file을 사용하기 위해
settings.py
에서 정의를 해줘야 한다.# settings.py # base 경로에 미디어 파일을 모으겠습니다! MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 내 서버에 !!$!@$/media/각각의파일의이름 이런식으로 파일들의 url을 만들어주겠다! MEDIA_URL = '/media/'
path를 추가해주자.
urls.py
로 가자.자.. 여기서 media 파일을 사용하기 위해 import 해줘야 하는 것!
# urls.py from django.conf import settings
아까 해준 media의 경로 설정을
urls.py
는 모르기 때문에 이녀석의 설정값을 알려줘야 내가 사용할 수 있다.# urls.py from django.conf import settings from django.conf.urls.static import static
이 녀석은 파일을 제공하는데 있어서 URL 패턴을 반환하는데 도움을 주는 함수를 import한 것이다.
애초에 media를 사용해서, URL을 추가하는 것이 조금 독특하기 때문에 그런것인데,
그 과정에서 오는 귀찮음을 이녀석을 가지고 해결할 수 있다.
static에서는 url로 내 사진 정보를 바로 들어갈 수 있지만
media 파일 같은 경우는 url로 들어가기 위해 다른 접근이 필요하다.
굉장히 귀찮은 짓을 해야하는데, 이 함수를 가져오면 문제가 가볍게 해결된다.
아마 서버를 돌릴 떄와, DEBUG 모드로 진입할 때 있어서 문제가 생기기 때문에 추가하는 것이 아닌가 싶다.(
어렵다)일단 이녀석은 잠깐 보류하자.
이미 media의 path는
settings.py
에서 정해놨기 때문에,urls.py
에서 path 를 추가해줄때,# urls.py 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)
기존 url추가 방식과 다르게 뒤에 병렬적으로 달아준다.
이렇게 할 경우 URL로 사용자가 업로드한 파일에 접근할 수 있다.
파이썬은 모든 것이 객체로 굴러가기 때문에 저 표현이,
어? 어떻게 리스트에 저런 방식으로 추가해!
라고 할수도 있겠지만 모든 것이 객체이기에 사실 urlpatterns 라는 객체가 어떻게 선언되어 있는지는
뜯어봐야 안다. (
사실 나도 너무 어렵다)저 추가 방식이 싫다면,
# urls.py urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
이렇게 써주어도 된다.
이제 사용자가 파일을 던지면 이 URL로 타고들어온다!
그러면 이 데이터를 우리의 model로 던져줘야 한다.
그러면 portfolio에서 받은 데이터를 model에 넣기 위해 class를 정의해줘야 한다.
# portfolio.models.py from django.db import models 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 # Create your models here.
이름, 이미지, 내용과 같은 3가지가 필요하고, 이걸 받기 위해서 model에 적용되어있는 메서드를 사용했다.
두번째,
ImageField
뒤의 파라미터는,image/
라는 경로에 이 이미지들을 받아 넣을 것이라는 의미에서저렇게 써주었다.
마지막
__str__
은 원래 객체가 탄생할 때 이녀석은 번호를 달고나오는데,난 번호를 달고나오는게 싫고, 이녀석을 땅! 하고 쳤을 때, 내가 달아준 제목이 나왔으면 좋겠다!
했을 때 저렇게 써주면 된다.
즉 객체자신의 이름을 설정해준다!
이렇게 클래스를 정의해줬으면, 모델한테 나 만들었어! 라고 알려줘야 한다.
그런데 그전에!
이미지를 모델에 넣고 싶으면 다른 패키지를 하나 깔아야 하는데,
$ pip install pillow
이 녀석이 무엇이냐!
파이썬으로 이미지처리를 쉽게해주는 녀석이다.
Python Image Library ~나중에 붙었어 low
이제 가자
$ python manage.py makemigrations $ python manage.py migrate
admin.py
에서 데이터를 넣을 거니까 여기에 알려주러 가자.# portfolio.admin.py from django.contrib import admin from .models import Portfolio admin.site.register(Portfolio) # Register your models here.
등록 완료!
자, 그러면 어떻게 접속해야 하는지도 알려줬고,경로도 설정해줬으며, 넘겨오는 데이터를 어떻게 받을지도
클래스로 정의해 줬다.
그런데, 중간단계, 즉 경로로 들어와서 어떻게 처리 가 되는지 안알려줬다!
즉, 받은 데이터를 정의된 클래스의 모델로 넘겨주는 작업이 안되어 있다.
이건
views.py
에서 가능!먼저 정의된 모델의 클래스를 써먹을 거니까 import 해주자.
그리고 생성된 객체들을 쿼리셋으로 다 받고, 이걸
portfolio.html
에서 써야되니딕셔너리 형으로 render함수에 껴서 반환하자.
# views.py from django.shortcuts import render from django.models import Portfolio def portfolio(request): portfolio = Portfolio.objects return render(request, 'portfolio.html', {'portfolios':portfolio}) # Create your views here.
이제 출력하자!
portfolio.html
로 가자.여기서 우리가 원하는 것은 데이터를 입력하면, 카드가 계속해서 나오는 것을 원한다.
그러니 card를 for문 안에 넣어줘야 하겠다!
<!-- portfolio.html --> {% for portfolio in portfolios.all %} <div class="col-md-4"> <div class="card mb-4 shadow-sm"> <img src = "{{portfolio.image.url}}" height = 400 alt = "기본사진"> <div class="card-body"> <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 %}
이렇게 넣어주자!
그런데 이제 static 파일 경로가 아니니까
{% static '킹밥.jpg' %}
이녀석을 지우고,media 파일을 적어주는 방식을 넣어주자.
{{portfolio.image.url}}
을 넣어준다.for문을 도는 변수가 portfolio라는 변수이고, 그것은 객체이기 때문에 그 안에있는 image를 긁어오며,
그리고 media 파일은 항상 URL을 타고오기 때문에 뒤에 적어준다.
참고로 템플릿 변수 {{}}
템플릿 태그 {%%}로 표현한다.
그 밑에 description을 넣어주고 싶으면
card-text
클래스에{{portfolio.description}}
을 적어주자.이녀석은 파일 이 아니므로 url을 적어줄 필요가 없다!
이제 서버를 키자!
/admin
으로 들어가서 추가하자!이렇게 내새끼가 또 나왔다!