CH9 Photo 앱

자무카·2021년 6월 11일
0

김석훈_장고_실전

목록 보기
1/1

개요

  1. [models.py]
    ::: 썸네일 기능을 위해, <커스텀 필드> 사용.
    (( 실제로는 sorl-thumbnail, django-imagekit, easy-thumbnails 이용 )
  2. [admin.py]
    ::: inline 클래스 이용 —> 앨범(pk) 추가/수정시, 하위(inline)으로 FK인 Photo 테이블 추가 FK인 PhotoInline
    ( 그 전에 admin 하면, 3가지 1) admin.ModelAdmin 2)list_display 3)@admin.register(모델명)
  3. urls.py
  4. view.py
  5. temeplate

velog 짱이다... 진짜 좋다. notion 에서 갈아탐.
시리즈로 묶이고, 제목이 목록화돼서, 우측에 뜨는 것이 넘 좋다
이건 알아야겠다. # 으로 제목, > 로 코멘트

models.py :ThumbnailImageField

# models.py
from photo.fields import ThumbnailImageField

class Album(models.Model):
	name = 
	description =

	class Meta:
		ordering = ('name',)

	def get_absolute_url(self):
		return reverse('photo:album_detail', args=(self.id, ))

class Photo(models.Model):
	album = models.ForeignKey(Album,
	title
	description
	image = ThumbnailImageField(upload_to='photo/%Y/%m')

admin.py Album의 FK인 PhotoInline 사용

( pk: Album , FK : Photo —> 앨범 하위(PhotoInline)으로, 2개씩 보여줌(extra)

from django.contrib import admin

from photo.models import Album, Photo

class PhotoInline(admin.StackedInline):
    model = Photo
    extra = 2

@admin.register(Album)
class AlbumAdmin(admin.ModelAdmin):
    inlines = (PhotoInline,)
    list_display = ('id', 'name', 'description')

@admin.register(Photo)
class PhotoAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'upload_dt')

커스텀필드로 썸네일 fields.py

import os
from PIL import Image
from django.db.models import ImageField
from django.db.models.fields.files import ImageFieldFile

# 파일 처리 클래스인 ImageFieldFile 과 파일필드인 ImageField 클래스를 만든다.
class ThumbnailImageFieldFile(ImageFieldFile):
    def _add_thumb(self, s):
        parts = s.split('.')
        parts.insert(-1, 'photo/album/add/thumb')
        if parts[-1].lower() not in ('jpeg', 'jpg'):
            parts[-1] = 'jpg'
        return '.'.join(parts)

    @property # 메소드를 멤버 변수처럼 사용할 수 있게 한다.
    def thumb_path(self):
        return self._add_thumb(self.path)

    @property
    def thumb_url(self):
        return self._add_thumb(self.url)

    def save(self, name, content, save=True):
        super().save(name, content, save)

        img = Image.open(self.path)
        size = (self.field.thumb_width, self.field.thumb_height)
        img.thumbnail(size)
        background = Image.new('RGB', size, (255, 255, 255))
        box = (int((size[0]-img.size[0])/2), int((size[1]-img.size[1])/2))
        background.paste(img, box)
        background.save(self.thumb_path, 'JPEG')

    def delete(self, save=True):
        if os.path.exists(self.thumb_path):
            os.remove(self.thumb_path)
        super().delete(save)

# models.py 에서 사용하는 필드인 ThumbnailImageField
class ThumbnailImageField(ImageField):
    # attr_class 에 파일 처리 클래스를 등록해준다.
    attr_class = ThumbnailImageFieldFile

    def __init__(self, verbose_name=None, thumb_width=128, thumb_height=128, **kwargs):
        self.thumb_width, self.thumb_height = thumb_width, thumb_height
        super().__init__(verbose_name, **kwargs)

mysites/urls.py

from django.conf import settings
# static() 메서드는 정적 파일 처리를 위해 url 패턴을 반환한다.
from django.conf.urls.static import static

from django.contrib import admin
from django.urls import path, include

from mysite.views import HomeView


urlpatterns = [
    path('admin/', admin.site.urls),
    path('', HomeView.as_view(), name='home'),
    path('bookmark/', include('bookmark.urls')),
    path('blog/', include('blog.urls')),
    path('photo/', include('photo.urls')),

] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

기존 url 패턴 뒤에 static()을 추가한다.
static(prefix, view=django.views.static.serve, **kwargs
/media/ URL 요청이 오면, django.views.static.serve 가 처리한다.
static.serve() 는 개발용이고, 실 운영시, httpd, nginx 사용.
처음이니 개념 정도 보고, 몇 가지 케이스 더 보면 익숙해질 듯.

photo/urls.py

from django.urls import path

from photo import views


app_name = 'photo'
urlpatterns = [

    # Example: /photo/
    path('', views.AlbumLV.as_view(), name='index'),

    # Example: /photo/album/, same as /photo/
    path('album', views.AlbumLV.as_view(), name='album_list'),

    # Example: /photo/album/99/
    path('album/<int:pk>/', views.AlbumDV.as_view(), name='album_detail'),

    # Example: /photo/photo/99/
    path('photo/<int:pk>/', views.PhotoDV.as_view(), name='photo_detail'),

]

소감

커스텀 필드를 직접 짠다 생각하니까 너무 어렵다. ㅠㅠ 실제로는 패키지를 설치해서 많이 사용한다.
image-kit, sorl-thumbnail, easy-thumbnails 등.
URLconf 코딩하기도 ...
지금까지 공부하다 가장 멘붕 왔던 챕터다 ㅠ

profile
가즈아

0개의 댓글