안녕하세요. 이번 시간에는 django의 Filefield들에 쓰는 upload_to에 대해 간단하게 알아보겠습니다. 문서도 같이 보면 좋겠습니다.

 


 먼저, item_file_path 함수를 보겠습니다. instance와 filename 2개를 받습니다. instance는 생성된 레코드의 id입니다. 그리고, filename은 파일의 이름을 의미합니다. 문서의 표를 참고하시면 됩니다. 이 두 정보를 받아서 리턴하는 값은 item/{레코드_id}/{파일이름}이 됩니다.

 

 

 다음 11번째 줄입니다. id와 file을 입력으로 받습니다. id라는 필드를 추가해 주었는데요. 왜 추가했는지는 밑에서 후술하겠습니다.

 

 

 이제, 파일을 업로드 해 보겠습니다. 파일 선택을 한 다음에 SAVE를 눌러보겠습니다.

 

 

 데이터베이스에 저장되어있는 파일 경로를 확인해 보겠습니다. 그랬더니, item/{uuid}/{파일이름} 으로 저장되었음을 볼 수 있습니다. upload_to에서 설정한 것과 똑같이 저장됩니다. 그러면, 실제 파일은 어디에 저장이 되었을까요?

 

 media 밑에 저장되어 있습니다. 즉, media/{데이터베이스에 저장되어 있는 파일 경로에 대한 정보} 로 접근하면 실제 파일을 얻어올 수 있는 셈이 됩니다. 그러면 이 media는 어디에서 왔을까요?

 

 

 settings.py에 MEDIA_ROOT를 media/로 설정하였습니다.

 

 다음에, urls.py에 MEDIA static 파일 경로에 document_root를 MEDIA_ROOT로 설정했습니다. 이 부분은 링크에서 언급했으니, 다시 보셔도 좋을 듯 싶어요. local에서의 media 파일들의 root 경로와 관련이 깊습니다. 고로, 파일을 찾아가기 위한 경로를 설정하기 위해 upload_to를 많이 쓴다고 생각하시면 좋겠습니다.

 

 해당 경로에 저장된 파일입니다.


 그런데 왜 굳이 uuid값을 pk로 삼고 default로 uuid.uuid4로 설정했을까요? 간단하게 요약하면, file path를 설정하는 시점에서는 instance의 id값을 얻어올 수 없기 때문입니다. 이는 문서에 나온, this object will not have been saved to the database yet, so if it users the default Autofield, it might not yet have a value와 관련이 깊습니다. 이를 해결할 수 있는 방안이 없을까요? 

 

 

 모델이 추가되고 난 후에, image의 path를 업데이트 (예를 들자면 signal을 이용)하는 방법이 있습니다.

 

 혹은, 서버가 직접 id를 생성하게 하는 방법이 있습니다. default=uuid.uuid4를 넘겨준 것이 그 의미입니다. 이미 서버에서 id 값을 채우기 위해 uuid.uuid4를 계산했습니다. 디비에서 계산하지 않기 때문에 upload_to에 걸린 item_file_path에서 instance.id를 알 수 있었다는 게 핵심이겠네요. 조금 더 자세한 내용은 뜯어보는 걸로 하도록 합시다.