안녕하세요, 오늘은 꽤나 많은 이야기를 다뤄보려 합니다.
다룰 내용들을 요약하면 다음과 같습니다.
- [1] MEDIA_URL, MEDIA_ROOT는 무엇인가?
- [2] setting.py에 MEDIA_URL, MEDIA_ROOT는 왜 적어주어야 하는가?
- [3] MEDIA_URL, MEDIA_ROOT를 왜 urlpatterns에 넣어주어야 하는가?
- [4] static함수의 동작 원리는 무엇인가?
- [5] urlpatterns 리스트의 기능은 무엇인가?
- [6] STATICFILES_DIR/ STATIC_URL / STATIC_ROOT와 MEDIA_URL, MEDIA_ROOT의 차이점은 무엇인가?
- [7] 왜 STATIC_URL은 urlpatterns에 추가하지 않는 것인가?
media라는 이름에서도 알 수 있듯, 이 둘은 사진을 받아오고 저장하기 위해 필요한 설정입니다.
settings.py파일에 아래의 코드를 입력해주세요.
#이건 유저가 올린 사진에 접근할 때 쓸 url
MEDIA_URL = '/media/'
#이건 유저가 올린 사진을 저장할 때 쓸 url
#model의 ImageFiled인자에 upload_to에 전달한 값이 a라면..
#유저가 업로드한 사진은 MEDIA_ROOT/a 디렉토리에 저장됨
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
유저가 업로드 한 사진이 저장될 디렉토리를 정하는데 사용됩니다.
유저가 업로드한 사진은, 사진을 저장하는 테이블 model클래스의 upload_to
에 전달된 값과 MEDIA_ROOT
를 결합한 위치인 MEDIA_ROOT/upload_to에 전달된 값
에 저장됩니다.
유저가 접근(조회)하는 사진의 url을 정해줍니다.
예를 들어, 유저가 1.jpg
라는 사진을 profile_imgs
폴더에 올렸다고 해봅시다.
from django.db import models
class PremiumMembers(models.Model):
#생략
#upload_to에 전달한 값..
#설정파일에 저장한 MEDIA_ROOT/upload_to값 디렉토리에 서비스 유저가 업로드한 사진 저장
profile_img = models.ImageField(upload_to='profile_imgs')
아래와 같이 모델에서 upload_to
의 값이 profile_imgs
이니, 유저가 사진을 업로드하면 그 사진은 MEDIA_ROOT/profile_imgs
폴더에 저장됩니다.
이후 유저가 그 사진을 조회하려 한다면,
http://example.com/media/profile_imgs/1.jpg
라는 url로 해당 사진을 조회할 수 있습니다.
결론은,
MEDIA_ROOT/upload_to값
경로에 유저가 올린 사진을 저장 하고,
서버주소/MEDIA_URL/upload_to값/사진이름
경로에서 유저가 원하는 사진을 화면에 띄워 주는 것입니다.
앞서 두 설정변수의 역할을 살펴보았으니, 이 질문에 대한 답이 어렴풋이 떠오릅니다.
유저가 업로드한 사진을 저장할 주소를 확보하고,
유저가 조회하려는 사진을 보여줄 주소도 확보하기 위함이겠네요.
urls.py파일의 urlpatterns
리스트는 "A라는 url에 들어오면/ X라는 동작을 수행한다" 라는 일종의 주소와 처리방식의 쌍을 적어두는 공간입니다.
아래는 프로젝트 폴더 내의 urls.py파일인데요,
urlpatterns라는 리스트 안에 path()
함수로 경로와 처리동작을 적어줍니다.
#projects/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', include('calc.urls')),
path("admin/", admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
path()
의 첫 인자는 url 주소, 두 번째 인자는 그 주소에 도달했을 때 일어날 동작을 받습니다. include()
함수는, 다른 app의 url을 포함시킬 때 사용합니다.
MEDIA_ROOT는 유저가 올린 사진을 저장해야하고
MEDIA_URL은 유저가 조회할 사진을 띄워줘야(서빙해줘야) 하니,
해당 주소에서의 동작을 처리해주기 위해 urlpatterns에 넣어주는 것입니다.
static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
이 부분만 자세히 더 알아봅시다.
path와 하는 일이 똑같은데, 처리할 동작이 사진과 같은 정적 자원을 다뤄야 한다면,
path 대신 static을 써주는 것입니다.
static함수는 첫 번째 인자로 요청을 받은 주소를 받습니다.
유저가 사진을 조회하고자 하는 위치인 MEDIA_URL이 잘 들어왔네요.
두 번째 인자는 요청된 자원을 찾을 공간입니다.
사진이 저장되어있는 ROOT를 잘 넣어주었네요.
static함수는 클라이언트가 요청하는 URL이 MEDIA_URL로 시작하면(해당 url에 접속하면), 해당 요청을 MEDIA_ROOT에서 실제 파일을 찾아 반환합니다(처리할 동작)
path()와 비슷하죠?
이건 위에서 충분히 답이 된 것 같습니다.
어떤 경로에서 어떤 동작을 처리해줄지 정해주는 녀석들을 모두 묶어둔 것이죠.
일종의 라우팅이라고 생각해도 괜찮을 것 같네요.
STATIC설정은 개발자가 개발할 때 정적 자원을 사용하기 위함이고,
MEDIA설정은 유저가 사진을 업로드하고 보도록 하기 위함입니다.
스태틱 설정에 관련된 내용들은 제 블로그 포스팅에서 자세히 다뤄두었으니,
한 번 보셔도 좋을 것 같습니다.
설정 파일엔 MEDIA설정 외에도 STATIC설정도 작성하는데요,
기억을 더듬어보면 이 친구들은 urlpatterns리스트에 포함시키지 않았는데요.
STATIC_URL = "static/"
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
왜 같은 정적 자원과 관련된 설정변수인 MEDIA는 url패턴 처리를 해주고,
STATIC은 해주지 않는 것일까요?
간단합니다! [6]번 항목에서 이미 답이 나왔지만,
STATIC설정은 유저가 url에 접속해서 요청과 응답을 주고받는 것과는 관련이 없기 때문입니다!
애초에 URL과 관련 없이, 개발할 때 css, js, 이미지 등의 정적 파일을 로드하기 위함이라는 것!