완숙의 블로그

[Django] Week 4_5 Blog & Portfolio Project_5 - media 본문

Programing Language/Web_Django

[Django] Week 4_5 Blog & Portfolio Project_5 - media

완숙 2019. 3. 9. 11:30

Media

프로젝트로 업로드 되는 파일

=> settings.py 에서 directory path, URL 을 지정해줘야 한다!

갑자기 URL? static에서는 없었는데..?

 

Static vs Media

Static 은 결국, 내 서버에 파일이 있는 경우를 의미하고,

Media는 남의 파일을 받아서 보여주는 것을 의미한다.

 

그렇다면 Static은 그냥 내가 저장해놓은 파일을 불러서 보여주면 되지만,

Media는 사용자가 업로드한 녀석을 내 서버에 받아두고, 이걸 다시 보여줘야 한다.

 

2019-02-27 11 23 36

 

그렇다면 통신에 관련되서라면 URL이 빠질 수가 없다,,

왜? URL을 기반으로 우리는 통신하니까!

 

우리가 해야할 일

  1. 파일이 어떤 URL 을 타고 들어올 것인지
  2. 그리고 그 파일들을 어디에 모아서 관리할 것인지

이걸 settings.py에서 관리해주면 되겠다.

 

2019-02-27 11 30 20

 

이렇게 정의를 했다면, 드디어 우리의 프로젝트한테 media 파일이 어떤식으로 들어올거야!

그리고 나중에 너가 이렇게 모아줘! 라고 말해준 격이다.

그러면 이제 이녀석도 알아먹었기 때문에

 

  1. 우리는 urls.py 에 가서 경로를 정해주고,
  2. 그 url을 타고 들어오는 media 데이터를 어떻게 model 안에 넣어줄 것인지 models.py 에서 클래스를 정의하고,
  3. DB한테 이런 친구 들어온다~ 하고 migration을 해서 또 프로젝트한테 알려주고,
  4. 우리는 /admin 에서 데이터를 집어 넣을 거니까, admin.pyadmin.site.register 를 해서 알려주고
  5. 이 데이터를 처리해서 보여주세요! 라는 정보처리에 관련된 views.py 에 함수도 정의를 해줘야 한다.
  6. 그리고 HTML을 띄우면 끝!

 

실습

  1. media file을 사용하기 위해 settings.py 에서 정의를 해줘야 한다.

    # settings.py
    # base 경로에 미디어 파일을 모으겠습니다!
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    
    # 내 서버에 !!$!@$/media/각각의파일의이름 이런식으로 파일들의 url을 만들어주겠다!
    MEDIA_URL = '/media/'
    

     

  2. 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 모드로 진입할 때 있어서 문제가 생기기 때문에 추가하는 것이 아닌가 싶다.(어렵다)

    일단 이녀석은 잠깐 보류하자.

     

  3. 이미 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)
    

    이렇게 써주어도 된다.

     

  4. 이제 사용자가 파일을 던지면 이 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__ 은 원래 객체가 탄생할 때 이녀석은 번호를 달고나오는데,

    난 번호를 달고나오는게 싫고, 이녀석을 땅! 하고 쳤을 때, 내가 달아준 제목이 나왔으면 좋겠다!

    했을 때 저렇게 써주면 된다.

    즉 객체자신의 이름을 설정해준다!

     

  5. 이렇게 클래스를 정의해줬으면, 모델한테 나 만들었어! 라고 알려줘야 한다.

    그런데 그전에!

    이미지를 모델에 넣고 싶으면 다른 패키지를 하나 깔아야 하는데,

    $ pip install pillow
    

    이 녀석이 무엇이냐!

    파이썬으로 이미지처리를 쉽게해주는 녀석이다.

    Python Image Library ~나중에 붙었어 low

     

  6. 이제 가자

    $ python manage.py makemigrations
    $ python manage.py migrate
    

     

  7. admin.py 에서 데이터를 넣을 거니까 여기에 알려주러 가자.

    # portfolio.admin.py
    from django.contrib import admin
    from .models import Portfolio
    
    admin.site.register(Portfolio)
    
    # Register your models here.
    

    등록 완료!

     

  8. 자, 그러면 어떻게 접속해야 하는지도 알려줬고,경로도 설정해줬으며, 넘겨오는 데이터를 어떻게 받을지도

    클래스로 정의해 줬다.

    그런데, 중간단계, 즉 경로로 들어와서 어떻게 처리 가 되는지 안알려줬다!

    즉, 받은 데이터를 정의된 클래스의 모델로 넘겨주는 작업이 안되어 있다.

    이건 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.
    

     

  9. 이제 출력하자! 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을 타고오기 때문에 뒤에 적어준다.

     

    참고로 템플릿 변수 {{}}

    템플릿 태그 {%%}로 표현한다.

     

  10. 그 밑에 description을 넣어주고 싶으면 card-text 클래스에

    {{portfolio.description}} 을 적어주자.

    이녀석은 파일 이 아니므로 url을 적어줄 필요가 없다!

     

  11. 이제 서버를 키자!

     

  12. /admin 으로 들어가서 추가하자!

    2019-02-28 1 11 33

     

  13. 이렇게 내새끼가 또 나왔다!

    2019-02-28 1 17 22

 

Comments