08.-2 사진 처리

조재훈·2022년 7월 21일
0

Clone_Airbnb

목록 보기
16/31
post-thumbnail

1) 사진 클릭시 열리게 하기

현재는 사진 업로드시 문제가 있다
1) 사진 파일이 폴더에 바로 업로드된다.

2) 사진 파일 링크가 제대로 안되어있다.

이를 해결하기 위해 MEDIA_ROOT 라는걸 설정해준다.
우리가 업로드한 파일들을 어디에 써야하는지 지정해주는 것이다.

https://docs.djangoproject.com/en/4.0/ref/settings/#std-setting-MEDIA_ROOT
config - settings.py

print(BASE_DIR)


MEDIA_ROOT는 절대경로가 되어야 한다. 이 BASE_DIR를 기반으로 사진들이 업로드될 경로를 이어붙여준다.

print(os.path.join(BASE_DIR, "uploads")

MEDIA_ROOT = os.path.join(BASE_DIR, "uploads")

이제 Photo에서 사진을 추가해보자

uploads 폴더가 생성되었다.

이러한 사진들이 전부 깃허브에 업로드되지 않기 위해 .gitignore에 uploads 폴더를 추가한다.

uploads/

그리고 위에서 설정한 폴더 내에서도 사진을 올릴 때 세부 경로를 지정해준다. rooms에서 사진을 올릴 때에는 room_photos 라는 세부 폴더로 업로드되게 하려고 한다.
ImageField는 FileField를 상속받는데 이 FileField의 기본 속성에 upload_to 가 있다.

rooms - models.py - Photo

    file = models.ImageField(upload_to="room_photos")

users - models.py - User

    avatar = models.ImageField(upload_to="avatars", blank=True)

migration을 해주자

Users와 Photos에 사진을 등록하고나면 아래와 같이 자동으로 지정된 경로에 폴더가 생성되고 사진이 저장된다.

하지만 admin 패널에서 링크를 클릭해보면 여전히 사진이 안뜬다.


이것은 현재 장고가 /uploads/room_photos 안에 들어갈 권한이 없기 때문이다.
저기서 주소창을 보면
/avatars/사진이름
으로 되어있다.
대신 MEDIA_URL이란걸 지정해준다. 가령 MEDIA_URL="/media/" 라고 써져있으면 누군가가 media라고 url을 붙이면 MEDIA_ROOT에 있는 파일들을 살펴보라고 해주는 것이다. 이렇게 해서 URL을 내 컴퓨터 안의 폴더와 연결할 수 있다.

config - settings.py

MEDIA_URL = "media/"

그러고나서 admin 패널에서 사진 URL을 확인해보면 media 글자가 붙어있는걸 볼 수 있다.

※장고 버전차이인지 모르겠는데 강의와는 다르게 별다른 설정을 하지도 않았는데 이미 짜잘한 폴더들이 전부 포함된 URL이 아니라 어느정도 정리가 된 URL이 남아있다. 일단 강의에서 하라는대로 진행은 하는데 특별히 달라지는 내용이 없을수도 있다.

현재는 상대 경로로 되어있는데 Root 에서 시작하는게 아니다. 절대 경로로 바꾸어주자

MEDIA_URL = "/media/"

이제 장고는 사진을 어디에 저장해야하고 어떤 URL에서 사진을 찾아야 하는지 알게 되었다.
위의 오류에서 보면 이런 문구가 있다.

Using the URLconf defined in config.urls, Django tried these URL patterns, in this order:
   1. admin/
The current path, [현재 URL] didn't match any of these.

장고한테 어떻게 폴더 안의 파일들을 제공하는지 알려주어야 한다. 이건 물론 개발단계에서만 하고 실제로 배포할때는 하지 않을 것이다. 왜냐면 배포할때 이렇게 하면 서버를 복제할 때 저장소가 단일화되지 않아서 그 내부의 파일들도 전부 복제가 되어 엉망진창이 되기 때문이다.
config에서 url을 지정해주자
config - urls.py

from django.conf import settings

이때 from . import settings 를 하면 안된다.

참고로 현재가 개발모드인지 실전모드인지 궁금할때는 settings.py에서 아래 문구를 확인하면 된다.

DEBUG = True

이 경우는 개발모드로서 아래와 같은 에러 페이지를 보여준다.

만약 바꾸어보면? 이때는 ALLOWED_HOSTS 라는 것도 지정해주어야 한다.

DEBUG = False

ALLOWED_HOSTS = ["*"]

다시 urls.py를 설정해주자.
config - urls.py

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [path("admin/", admin.site.urls)]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)



저 static 함수를 타고 들어가서 살펴보면 view를 가진 path를 반환한다.

2) PhotoAdmin 설정

rooms - admin.py - PhotoAdmin

    list_display = ("__str__", "get_thumbnail")
    
    def get_thumbnail(self, obj):
        print(obj.file)
        return ""
    
    get_thumbnail.short_description = "Thumbnail"


파일 내부도 살펴보자

        print(dir(obj.file))


ImageField는 단순히 사진파일이 아니라 여러 정보를 담고있는 Class 였다. 그 중 몇가지를 살펴보자.

        print(obj.file.path)

        print(obj.file.url)

        print(obj.file.height)


'ㅅ'........ 뭐가 문제일까 한참을 고민했는데 알고보니 저 폴더에 사진이 업로드가 안되어있다.

다시 사진을 제대로 업로드하고서 height를 찍어보니 잘 나온다.

아무튼 해결되었으니 진짜로 코드를 짜보면

    def get_thumbnail(self, obj):
        return obj.file.url


저 주소에 있는 사진이 뜨게 하려면

    def get_thumbnail(self, obj):
        return f'<img src="{obj.file.url}" />'


'ㅂ'........ 보안때메 그렇다고 한다. 왜냐면 자동으로 코드가 실행될 경우 이상한 악성코드를 업로드해서 자동으로 실행시켜버릴수도 있기 때문에 그렇다네.
그래서 이 코드는 안전하다는걸 알려주어야 한다.
rooms - admin.py

from django.utils.html import mark_safe

...

    def get_thumbnail(self, obj):
        return mark_safe(f'<img src="{obj.file.url}" />')



근데 사진이 너무 크다.

    def get_thumbnail(self, obj):
        return mark_safe(f'<img width=50px height=50px src="{obj.file.url}" />')

profile
맨땅에 헤딩. 인생은 실전.

0개의 댓글