Django 5

김기현·2022년 2월 4일
0

django

목록 보기
5/8
post-thumbnail

사진이나 미디어를 유저들이 업로드하는데, 아무런 조치 없이 업로드할 순 없습니다. 이번 파트에서는 user upload에 관해 다루어보겠습니다.

Configure User Uploads

MEDIA_ROOT

MEDIA_ROOT 어디에다 우리가 업로드한 파일을 써야 할 지 말해주는 곳입니다.

settings.py에 MEDIA_ROOT = BASE_DIR / "uploads"합니다. 그 후 파일을 업로드하면 uploads라는 폴더가 생성된 것을 확인할 수 있습니다. gitignore에 uploads/를 추가해 사진 파일들이 업로드되지 않도록 합니다.

django 3.1 미만의 버전으로 startproject하면 TypeError: unsupported operand type(s) for /: 'str' and 'str'오류가 발생할 수 있으므로 버전확인을 합니다.

다음의 코드를 분석합니다.

class Photo(core_models.TimeStampedModel):

    caption = models.CharField(max_length=80)
    file = models.ImageField(upload_to="room_photos")  # room_photos라는 폴더에 사진 저장됨
    room = models.ForeignKey("Room", related_name="photos", on_delete=models.CASCADE)

    def __str__(self):
        return self.caption

file은 upload_to를 사용해 저장하려는 경로를 지정해주었는데요! 이로써 uploads/room_photos에 저장됩니다. migrate는 필수!

그!러!나! 저장은 원하는 대로 잘 되지만 관리자 페이지에서 사진링크파일을 열면 장고가 사진위치에 접근할 수 없다고 말하는데요~

url을 내 컴퓨터 안의 폴더와 연결해야 장고가 해당 위치에 접근가능합니다.

MEDIA_URL

MEDIA_URL은 MEDIA_ROOT에서 온 MEDIA를 다룹니다. settings.py에 MEDIA_URL = "media/"를 입력합니다. 만약 uploads폴더로부터 사진을 가져오고 싶다면 /media/room_photos/에 접근해야 합니다. 그래서 uploads 디렉토리를 MEDIA_URL과 연결합니다.

연결을 완료하면 내가 어디에 있는지에 따라 상대적인 상대경로로 url을 만들어줍니다. 하지만 Root에 있는 것이 원하는 것이므로 MEDIA_URL = "/media/"로 만들어줍니다. '/media/'는 절대경로로 만들어줍니다. 그러나 Page not found에러를 보여줍니다.


에러를 보면 Using the URLconf defined in config.urls라고 나옵니다.

URL_conf 변경

이제 절반왔습니다. urlpatterns에 새로운 static 경로를 등록해주면 이 여정은 끝이 납니다.

장고가 사진을 어디에 저장해야 하는지 알고, 어떤 url에서 사진을 찾을 수 있는지 알고 있습니다. 이제는 장고에게 사진을 보여달라고 말해야 합니다.

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

urlpatterns = [
    path("", include("core.urls", namespace="core")),
    path("rooms/", include("rooms.urls", namespace="rooms")),
    path("admin/", admin.site.urls),
]

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

config/settings.py에서 from django.conf import settings를 합니다. settings을 임포트함으로서 변경된 부분이 settings.py에 자동적으로 반영됩니다.

다음으로 static을 사용해 경로를 등록합니다. settings.DEBUG이 True일 때 작동되도록 한 것으로 Amazon이나 Heroku에선 다른 저장소에 의해 사진이 제공되므로 이처럼 작동되는 것을 원치 않습니다. 그렇지 않으면 코드 서버에서 더 많은 디스크 공간을 소비하게 됩니다.

위 방법은 개발 모드에서만 작업된 부분으로 배포 때는 Amazon s3의 다른 저장소에 저장되도록 합니다!

Photo Admin

from django.utils.html import mark_safe

@admin.register(models.Photo)
class PhotoAdmin(admin.ModelAdmin):

    list_display = ("__str__", "get_thumbnail")

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

    get_thumbnail.short_description = "Thumbnail"

그냥 사진파일의 url을 입력하면 장고는 security에 의해 스크립트가 실행되지 않도록 되어있습니다. 따라서 mark_safe로 안전하다고 선언한 후 스크립트를 실행합니다.

profile
피자, 코드, 커피를 사랑하는 피코커

0개의 댓글