관리 메뉴

Storage Gonie

51. (app3) Django 썸네일 만들기 본문

웹개발/Django 웹서비스 개발(인프런)

51. (app3) Django 썸네일 만들기

Storage Gonie 2019. 3. 1. 03:32
반응형

쎔네일기능을 직접 구현할 수 있으나, 파일 I/O작업도 있고 복잡하여 아래의 오픈소스를 이용한다.

여기서는 좀 더 간단한 sorl-thumbnail을 이용하도록 한다.


1) sorl-thumbnail(https://github.com/jazzband/sorl-thumbnail)

2) django-imagekit(https://github.com/matthewwithanm/django-imagekit)



1. sorl-thumbnail 설치

- 장고 1.10 버전에서는 그냥 설치하면 에러가 나므로 아래의 방법으로 설치한다.

- 가상환경을 실행한 후 아래의 명령어 입력하여 깃허브에서 직접 가져와 설치한다.

- "pip install -e git+https://github.com/mariocesar/sorl-thumbnail.git#egg=sorl-thumbnail"


2. settings.py의 INSTALLED_APP의 맨 아래에 추가해준다.

INSTALLED_APPS = [ ...
'sorl.thumbnail',
]

3. models.py에서 Photo 모델을 수정한다.

- thumbnail_image 필드를 제거한다. 이유는 원래 Celery 비동기 를 사용하여 자동으로 썸네일 이미지가 만들어지도록 할 의도였으나 난이도가 높아져 진로수정.

- is_public 필드를 추가한다. 나중에 공개로 설정되어있는 사진만 보여지도록 하기 위해

- __str__오버라이딩 함수를 생성해준다. admin페이지에서 객체 내용 확인이 쉽도록하기 위해

class Photo(models.Model):
image = models.ImageField(upload_to=user_path) # upload_to로 어디에 업로드할지 지정할 수 있음.
owner = models.ForeignKey(settings.AUTH_USER_MODEL) # 하나의 사진은 한명의 사용자에게 속해야 하므로. 1:N의 관계
# thumbnail_image = models.ImageField(blank=True) # blank가 True이면 폼 입력시 꼭 입력하지 않아도 된다는 의미
comment = models.CharField(max_length=255)
pub_date = models.DateTimeField(auto_now_add=True) # 사용자가 입력하지 않고 업로드 하는 순간 자동으로 세팅이 됨.
is_public = models.BooleanField(default=False) # 비공개 사진인지, 공개 사진인지에 대한 필드

# 객체를 출력하면 보고싶은 내용 수정(함수 오버라이딩)
def __str__(self):
return '{} {} {}'.format(self.owner.username, self.comment, self.is_public)

4. models.py에 아래의 코드 삽입

- 이유는 사용법이 그러한 것이므로 깃허브 참고.

- sorl-thumbnail(https://github.com/jazzband/sorl-thumbnail)

from sorl.thumbnail import ImageField


5. 모델이 수정되었으므로 다음 작업을 해줌

- "python manage.py makemigrations"

- "python manage.py migrate"

- 공개 or 비공개 기능이 추가된게 확인됨.




6. views.py에서 프로필만을 보여주던 ProfileView를 주석처리하고 profile메소드를 만들어 프로필 및 공개한 사진들 까지 보여지도록한다.

@login_required
def profile(request, pk):
user = get_object_or_404(User, pk=pk)
photos = user.photo_set.filter(is_public=True)[:20]
context = {"profile_user": user, "photos": photos}
return render(request, 'kilogram/profile.html', context)


'''
class ProfileView(DetailView):
context_object_name = 'profile_user' # model로 지정해준 User모델에 대한 객체와 로그인한 사용자랑 명칭이 겹쳐버리기 때문에 이를 지정해줌.
model = User
template_name = 'kilogram/profile.html'
'''

7. kilogram/urls.py에서 profile을 보여주는 url을 ProfileView과 연결되는게 아닌 위에서 만든 profile 메소드와 연결시킨다.

- 원래의 url을 수정한다.

url(r'^profile/(?P<pk>[0-9]+)/$', login_required(views.ProfileView.as_view()), name='profile'),
url(r'^profile/(?P<pk>[0-9]+)/$', views.profile, name='profile'),

8. templates/kilogram/profile.html 수정1

- 첫번째 꺼에서는 'username' 'name' 이런 쓸대없는 텍스트 지움

- 두번째 꺼는 아래에 코드 삽입.

- 수정된 화면의 결과는 아래와 같다.

<h3> {{profile_user.username}} <br>
{% if profile_user.first_name is not None %}
{{profile_user.first_name}} {{profile_user.last_name}} <br>
{% endif %}
</h3>
<div class="row">
{% for photo in photos %}
{{photo}}
{% endfor %}
</div>

8. templates/kilogram/profile.html 수정2

- 이번엔 아래의 코드를 두번째의 코드로 대체한다.

- 그리고 세번째의 코드를 {% load staticfiles %} 바로 아래에 넣어준다.

- 썸네일의 사용법은 도큐먼트를 보면 알 수 있다.

<div class="row">
{% for photo in photos %}
{{photo}}
{% endfor %}
</div>

<p> </p>
<div class="row">
{%for photo in photos %}
<div class="col-xs-6 col-md-4">
{% thumbnail photo.image "300x300" crop="center" as im %}
<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
{% endthumbnail %}
</div>
{% endfor %}
</div>

{% load thumbnail %}


9. 보여지는 사진은 캐시된 이미지라서 작게 잘려진 것이고, 원본 사진은 그대로 존재한다.

반응형
Comments