이미지 리사이징 및 글쓰기 글수정 페이지 합치기

‍한승운·2021년 3월 22일
0

django

목록 보기
7/23
post-thumbnail
post-custom-banner
  • 사용자가 올리는 사진의 크기는 제각각이다.
  • 그래서 웹페이지를 구성할 때 같은 크기로 출력되게 하고싶으면 두가지 방법이 있다.
    1. HTML 에서 이미지 크기를 정해주고 출력을 하게 하기
      • 고화질 사진은 줄이느라 깨지고, 저화질 사진은 늘리느라 깨짐
      • 목록과 같은 작은 사진이 필요할 때 고해상도의 무거운 사진을 불러오게 되면, 통신에 소모되는 용량과 시간이 크게 됨
    2. 유저가 올린 사진 자체를 형태를 바꿔서 저장
      • 인스타의 경우, 목적에 따라 모든 사진은 resizing 함

1. Django-imagekit

1.1 설치

1.2 사용하기

1.2.1 방법1

  1. 어플.models.py
    • 다 하고 python manage.py makemigrations 를 해도 No changes detected가 뜨게됨
    • 이 방법은 따로 리사이징 된 파일을 저장하는 것이 아닌 썸네일을 필요로 하는 상황에 작업을 해서 보여주는 방식이다.
from django.db import models
from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFill

# Create your models here.
class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    image = models.ImageField(blank=True)

    # source = 뭐를 기준으로 만들지 - imageField 변수명이 들어감
    # processors - 작업내용
    ## ResizeToFill = 리사이징된 크기 정해주기
    # format - 확장자
    # quality - 해상도
    image_thumbnail = ImageSpecField(source='image',
                                      processors=[ResizeToFill(200, 200)], 
                                      format='JPEG',
                                      options={'quality': 60})

    created_at = models.DateTimeField(auto_now_add=True)
  1. 리사이징 된 사이즈를 HTML에 사용하기

    • <img src="{{ post.image_thumbnail.url }}" class="card-img-top" alt="{{ post.image }}">
  2. 리사이징 된 사진 찾아보기

    • 데이터베이스에 보면 리사이징된 이미지에 대한 정보는 따로 데이터베이스에 저장되지 않음

    • media 폴더 > CACHE > images > 사진명 폴더에 따로 저장되어있음

1.2.2 방법2

  1. 어플.models.py

    from django.db import models
    from imagekit.models import ProcessedImageField
    from imagekit.processors import ResizeToFill
    
    # Create your models here.
    class Post(models.Model):
        title = models.CharField(max_length=100)
        content = models.TextField()
        # upload_to : 어느폴더에 올릴지 선택
        ## media 폴더 안에 upload_to 에 준 이름 폴더에 리사이징된 사진이 저장되게 됨
        image = ProcessedImageField(upload_to='image_thumb',
                                               processors=[ResizeToFill(100, 50)],
                                               format='JPEG',
                                               options={'quality': 60})
    
        created_at = models.DateTimeField(auto_now_add=True)
  2. 데이터 베이스에 적용하기

    • python manage.py makemigrations
    • python manage.py migrate

1.2.3 날짜에 따라 올린 사진을 구분해서 저장하기

  1. 어플.models.py 에서 바꿔주기

    • upload_to 매개변수에 %Y/%m/%d/를 넣어 연/월/일 을 붙여서 폴더가 생성되게 함
    image = ProcessedImageField(upload_to='images/%Y/%m/%d/',
                                                processors=[ResizeToFill(100, 50)],
                                                format='JPEG',
                                                options={'quality': 60})

2. 글쓰기와 글수정 페이지 합치기

  • 글쓰는 페이지와 글 수정페이지는 거의 대부분의 코드가 동일하다

    그래서 페이지를 나눠서 관리하는 것 비효율적이다.

  • 그러기 위해서 request 객체가 어떤 것을 통과하고, 어떤 요소를 가지고 있는지

2.1 request

2.2 실제로 합쳐보기

  1. 어플.form.html

    • request.resolver_match.url_name 는 현재 들어온 주소랑 매칭시키는 역할
      • url_name은 urls.py에서 path 맨뒤에 적은 name 매개변수와 연동됨
      • https://docs.djangoproject.com/en/3.1/ref/urlresolvers/#django.urls.ResolverMatch
      • resolver_match 가 쓸 수 있는 것들
        • url_name : URL과 일치하는 URL 패턴의 이름
        • route : 일치하는 URL 패턴의 경로
        • app_name : URL 과 일치하는 URL 패턴의 애플리케이션 네임 스페이스
        • namespace : URL과 일치하는 URL 패턴의 인스턴스 네임 스페이스
    {% extends 'base.html' %}
    {% load bootstrap5 %}
    
    {% block content %}
      {% if request.resolver_match.url_name == 'create' %}
        <div class="fs-3 text-center bg-info p-3">create</div>
      {% else %}
        <div class="fs-3 text-center bg-warning p-3">update</div>
      {% endif %}
      <form action="" method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        {% bootstrap_form form %}
        <input class="btn btn-primary" type="submit">
      </form>
    {% endblock content %}
  2. 어플.views.py

    • create 함수부분의 render 페이지를 바꿔줌
      • return render(request, 'posts/form.html', context)
    • update 함수부분의 render 페이지를 바꿔줌
      • return render(request, 'posts/form.html', context)

3. 찾는 게시글이 없을 때 에러 발생하게 하기

profile
함께 성장하고 싶은 백엔드 개발자
post-custom-banner

0개의 댓글