-
TIL 2023.06.22내일배움캠프 2023. 6. 22. 19:32
DRF의 페이지네이션은
파일 경로에 서버 url를 같이 담아서 보내준다는 걸 알았다.
이걸 발견한 게 백엔드 서버를 배포했을 때,
사진을 제대로 불러오지 못한 부분에서 왜 그런지 한참 찾아보다가 알게 되었다.
img src=에 http://backend:8000 이 부분은 써 준 적도 없는데 붙어있던 것이다.
이미지 파일 경로는 DB에 /media/~ 이런 식으로 저장되지만
페이지네이션으로 가져올 때는 앞에 서버 주소를 자동으로 붙여서 보내주게 된다.
로컬서버에서는 http://127.0.0.1:8000/media/~ 이런식으로
경로를 알아서 만들어줘서 오 이거 왜 자동으로 써 있지 하며 좋아했지만,
docker로 배포한 환경에서는 http://backend:8000/media/~ 이런 식으로 나왔다.
저 경로로는 이미지를 불러 올 수 없다.
그래서 페이지네이션을 커스텀하면 앞에 서버 주소를 지워줄 수 있다.
먼저 이미지 파일 경로는
class PostListAPIView(ListAPIView): queryset = Post.objects.all() serializer_class = PostListSerializer pagination_class = PostPageNumberPagination def get_serializer_context(self): return { 'request': None, # None이 아닌 경우에 full url 표시 'format': self.format_kwarg, 'view': self }
이렇게 ListAPIView를 상속 받아서, get_serializer_context 함수를 오버라이딩해서 지워주면 된다.
이걸 각 앱에 적용 시켰다.
또 next와 previous 경로에서도 서버 주소가 붙어서 나왔는데,
이건 다른 방식으로 해결해야 했다.
from rest_framework.utils.urls import remove_query_param, replace_query_param from rest_framework import pagination class CustomPagination(pagination.PageNumberPagination): def get_next_link(self): if not self.page.has_next(): return None url = self.request.build_absolute_uri() url = url.split('/')[3:] url = "/" + "/".join(url) page_number = self.page.next_page_number() return replace_query_param(url, self.page_query_param, page_number) def get_previous_link(self): if not self.page.has_previous(): return None url = self.request.build_absolute_uri() url = url.split('/')[3:] url = "/" + "/".join(url) page_number = self.page.previous_page_number() if page_number == 1: return remove_query_param(url, self.page_query_param) return replace_query_param(url, self.page_query_param, page_number)
PageNumberPagination 을 상속하여 커스텀페이지네이션을 만들고
url로 선언한 경로를 / 를 기준으로 쪼개서 앞 부분을 슬라이싱 해주고
다시 붙여준다.
그리고 settings.py에 기본 페이지네이션 클래스를 지정해준다.
REST_FRAMEWORK = { "DEFAULT_PAGINATION_CLASS": "spots.core.pagination.CustomPagination", "PAGE_SIZE": 6, }
이렇게 페이지네이션 시 서버 주소를 자동으로 붙여주는 문제를 해결할 수 있었다.
다른 문제
nginx 에선 기본 파일 업로드 제한을 1MB 로 걸어 두고 있다.
이 때 413 Request Entity Too Large 코드를 뱉어 내는 게 정상인데,
이상하게도 우리 서버는 cors 에러를 뱉어 냈다.
어쨌든 그 문제를 해결하고자 nginx의 파일 크기 제한을 3MB로 늘려 주었다.
sudo vi /etc/nginx/nginx.conf
nignx.conf 를 열어서
http { 안에
client_max_body_size 3M;
이런 설정을 추가 해주면 된다.
그리고 프론트에서도 예외처리를 해준다.
const image = document.getElementById("image-select").files[0]; let maxSize = 3 * 1024 * 1024; //=>3MB if (image.size > maxSize) { return alert("3MB 이하의 파일만 업로드 가능합니다.") }
나는 이렇게 코드를 짰다.
token refresh 기능도 추가했다.
document.addEventListener('DOMContentLoaded', async function () { tokenRefresh() }) async function tokenRefresh() { const refresh = localStorage.getItem("refresh") if (refresh) { const response = await fetch(`${proxy}/users/api/token/refresh/`, { headers: { "content-type": "application/json", }, method: "POST", body: JSON.stringify({ refresh: refresh }) }); if (response.status == 200) { const response_json = await response.json(); localStorage.setItem("access", response_json.access); } else { handleLogout() } } }
페이지가 로드 되면 tokenRefresh() 함수를 호출한다.
tokenRefresh() 함수는 로컬스토리지에 리프레시 토큰이 있는 지 확인하고
있다면 서버로 전송해 엑세스 토큰을 새로 받아와 로컬스토리지에 저장한다.
만약 스테이터스 코드가 200이 아니라면 리프레시 토큰이 만료됐을 확률이 크기 때문에
handleLogout() 함수를 호출하는데 handleLogout() 는 로컬스토리지의 토큰을 모두 지운다.
'내일배움캠프' 카테고리의 다른 글
WIL 내일배움캠프 15주차 (0) 2023.06.23 TIL 2023.06.23 (0) 2023.06.23 TIL 2023.06.21 (0) 2023.06.21 TIL 2023.06.20 (0) 2023.06.20 TIL 2023.06.19 (0) 2023.06.19