0부터 시작하는 Django 공부 - 파일 업로드

Jaehong Lee·2022년 6월 24일
0
post-thumbnail

1. 사용할 간단한 게시판 구현


1. app 추가
2. model 추가, migration
3. form 추가
4. view에 함수 추가
5. template 추가
6. url 추가

  • 파일 업로드는 1:1 일수도 1:N 일수도 있다

2. 파일 업로드 - 1:1

  • 2.1 model 설정

    • models에 imagefield를 추가한다.
    • null은 DB에 저장될 때 빈 공간을 허용하는 옵션
    • blank는 입력 양식에 저장할 때 빈 공간을 허용하는 옵션
    • upload to는 저장할 directory를 지정한다. 이때 static 폴더와 받아올 img에 대한 폴더를 분리해야 한다
  • 2.2 media 폴더 생성 및 settings.py에 경로 지정

    • media 폴더 안에 images 폴더 안에 저장된다
    • media_root는 업로드 한 파일 FileField이 이동할 폴더이다
    • 즉, media/images/ 안에 image들이 저장된다
    • 리스트가 아닌 단일로 설정하는 이유는 Django가 그렇게 하라고 했기 때문이다
  • 2.3 pillow 설치

    • Python에서 img를 다루는 라이브러리
  • 2.4 migration

  • 2.5 form 수정

    • fields에 추가한다
    • 이미지 파일 선택이 추가된다
  • 2.6 html 수정

    • enctype : 폼 데이터(form data)가 서버로 제출될 때 해당 데이터가 인코딩되는 방법
    • "multipart/form-data" : 파일이나 이미지를 서버로 전송할 때 인코딩 되면 파일의 경로명만 전송되고 파일 내용이 전송되지 않기 때문에 모든 문자를 인코딩하지 않음을 명시하는 옵션이다
  • 2.7 views 수정

    • 파일은 request.POST가 아니라 request.FILES로 받아진다
    • image 파일은 파일시스템에, DB에는 image 경로가 저장
    • request 안에 FILES안에 image 속성으로 받아온 파일은 가져온다
  • 2.8 저장 확인

    • image 파일은 파일시스템에, DB에는 image 경로가 저장
    • image 파일이 지정한 폴더에 저장되었다
    • image 파일을 중복으로 저장하면, image 파일이 복사되며 이름 뒤에 추가 코드가 붙는다
  • 2.9 image 출력

    • img 태크를 이용해 설정한 폴더인 media + DB에 저장된 image 주소로 image를 출력한다. 하지만 image가 나오지는 않을거다. 그 이유는 STATIC과 다르게 MEDIA URL과 폴더 경로는 Django에 내장된 것이 아닌 사용자가 임의로 작성한 변수이기 때문이다
    • 이 두가지는 사용자가 임의로 작성한 변수이므로 URL에 사용하겠다고 설정해야한다
    • static을 통해 settings에 설정한 URL과 DIRECTORY 경로를 URL에 붙인다
    • import 해줘야한다

3. 파일 업로드 - 1:N

  • 3.1 model 추가

    • 1:N 관계이므로 ForeignKey를 통해 관계를 추가한다. 하나의 게시글안에 여러 image가 저장되므로 1:N 관계다
    • 게시글과 image를 서로 다른 model을 통해 받아와야하기에 상속을 사용한다
    • model이 수정되었으므로 migrate도 해준다
  • 3.2 HTML 수정

    • multiple 옵션을 통해 여러 파일을 한번에 입력받는다
    • image는 따로 입력받기에 input을 추가한다
  • 3.3 views 수정

    • postimage가 board를 상속받으므로, 게시글을 따로 postform을 통해 board객체를 만들어 저장하고, postimage 모델 객체를 만들어 Image를 저장받아 postimage의 board에 board객체를 넣어주고 save한다
    • multiple을 통해 여러 Image를 받아오므로 getlist를 통해 image 속성의 모든 Image을 받아 다 저장한다
  • 3.4 실행 결과

    • 여러 파일이 받아진다
    • Image를 따로 저장받으므로 새 table에 저장된다
  • 3.5 Image 출력

  • 1번 방법 ( 별로 안좋음 ).

    • views 수정
    • postimage는 board를 상속 받는다. 먼저, bid는 게시글 번호, 즉, board의 id이므로 bid를 통해 board model의 Data를 post하는 model 객체를 만들어 저장해주고, 이 post의 id를 이용해 image들을 가져와서 html에 보내준다. 이때, image는 다수이므로 filter를 통해 list로 가져온다
    • html 수정
    • post는 단일 Data지만, image는 다수이므로 filter를 통해 list로 받아왔다. 따라서, for문을 통해 media에 저장된 image들을 출력한다
    • 실행 결과
  • 2번 방법.

    • views 수정
    • prefetch_related를 통해 post를 상속받는 postimage의 image들을 가져온다. postimage_set의 post_image는 DB에 저장된 이름이다
    • 즉 , board에 대한 query를 실행해 bid에 대한 Data를 받아오고, 가져온 board에서 board의 id에 대해 postimage에서 query를 실행해 Data를 가져온다
    • html 수정
    • post의 postimage_set는 list 형태로 다수의 image들이 담겨있다. 그러므로 .all을 통해 전부 가져와서 for문을 통해 image를 출력한다
    • 실행 결과

4. 파일 업로드 방식의 속도 차이

  • 빨리 처리되는 곳 : 이미지 선택시 게시글 작성하는 동안 미리 업로드하여, 작성 완료시 텍스트만 업로드하는 곳
  • 느리게 처리되는 곳 : 만약 게시글을 작성할때 이미지 업로드를 게시글 작성 완료시 한번에 업로드하는 곳
profile
멋진 엔지니어가 될 때까지

0개의 댓글

관련 채용 정보