Django 템플릿에서 URL 꺼내기: request.path vs path_info vs get_full_path vs build_absolute_uri
Django 템플릿에서 현재 URL이 필요할 때가 많습니다.
- 네비게이션 “현재 메뉴 활성화”
- 로그인 후 “원래 보던 페이지로 돌아가기(next)”
- canonical URL / 공유 링크 만들기
- 쿼리스트링 포함해서 “현재 페이지 그대로” 링크 만들기
그런데 {{ request.path }} 말고도 비슷한 애들이 여럿이라 헷갈리죠.
오늘은 헷갈리기 쉬운 아래의 4개만 깔끔하게 비교합니다.
request.pathrequest.path_inforequest.get_full_path()request.build_absolute_uri()
{{ request }}는 대체 어디서 오는가
템플릿에서 {{ request }}가 보인다는 건, 보통 request context processor가 켜져 있다는 뜻입니다.
django.template.context_processors.request가 템플릿 컨텍스트에request를 넣어주는 역할을 합니다.- 이 context processor는
TEMPLATES설정의OPTIONS['context_processors']에 등록될 때 동작합니다.
즉, Django는 settings.TEMPLATES 에 request를 글로벌 컨텍스트로 넣어주도록 기본으로 설정되어있기 때문에 개발자가 고의로 이 설정을 지우지 않는 이상 Django 사용자는 아무런 불편함없이 당연하듯 사용하게 됩니다.
그리고 request 객체 자체는 Django가 요청을 받을 때 HttpRequest(실제로는 WSGI/ASGI request subclass)를 만들어서 뷰까지 넘겨주는 그 객체입니다. 이 객체에 path, path_info 같은 속성이 들어있어요.

한 줄 결론: 4개를 이렇게 외우면 편하다
path: “도메인 제외, 경로만”path_info: “앱이 보는 진짜 경로(스크립트 prefix 제외)”get_full_path(): “path+ 쿼리스트링”build_absolute_uri(): “스킴+호스트+경로까지 전부(완전한 URL)”
이제 각각을 정확히 보죠.
1) request.path : 도메인 없는 “경로(path)”
request.path는 도메인/스킴 없이 요청 경로만 줍니다. 예시는 이런 형태예요.
/music/bands/the_beatles/
언제 유용한가
- 메뉴 활성화 같은 단순 비교
django
{% if request.path == "/settings/" %}active{% endif %}
* “이 페이지는 어디 카테고리?” 같이 prefix 비교
django
{% if request.path|slice:":5" == "/api/" %}...{% endif %}
2) request.path_info : 배포환경에 덜 흔들리는 “실제 경로”
Django 문서에서 핵심 포인트는 이거예요.
- 어떤 서버 설정에서는 URL 경로가 스크립트 prefix(SCRIPT_NAME) 와 path info 로 나뉘는데,
path_info는 그중 path info 부분을 항상 담는다 (즉, 환경에 덜 의존)
쉽게 말해, 앱이 /app 같은 prefix 아래에 마운트되는 구성(리버스 프록시, 서브패스 배포 등)에서 path와 path_info가 달라질 수 있습니다.
언제 유용한가
- 서브패스 배포(예:
/app/아래로 서비스) 같은 환경을 고려해 “앱 기준 경로”로 판단하고 싶을 때 - 테스트/운영 서버에서 prefix가 달라질 수 있을 때
평소 단일 도메인 루트(
/)에서만 돌면path와path_info가 같아서 차이를 못 느끼는 경우가 많습니다. 하지만 환경이 바뀌면 그때부터 차이가 의미 있어집니다.
3) request.get_full_path() : path + 쿼리스트링까지
get_full_path()는 path에 쿼리스트링을 붙인 값을 반환합니다. 예시는 이런 형태입니다.
/music/bands/the_beatles/?print=true
언제 유용한가
- “현재 페이지 그대로 공유/리프레시/되돌아가기” 링크가 필요할 때
django
<a href="{{ request.get_full_path }}">새로고침 링크</a>
* 로그인/권한 체크 후 원래 페이지로 돌아가게 next 만들 때
django
<a href="/login/?next={{ request.get_full_path|urlencode }}">로그인</a>
참고로 Django에는
get_full_path()말고get_full_path_info()도 있는데, 후자는path_info기반으로 동작합니다. (오늘 비교 대상은 아니지만 차이를 알고 있으면 좋습니다.)
4) request.build_absolute_uri() : 스킴+도메인까지 포함한 “완전한 URL”
build_absolute_uri()는 현재 요청을 기준으로 절대 URL(absolute URI) 을 만들어 줍니다.
대충 이런 형태가 됩니다.
https://example.com/music/bands/the_beatles/?print=true
언제 유용한가
- 이메일/메신저 공유 링크처럼 도메인이 반드시 필요한 경우
- canonical URL, og:url 같은 메타 태그
- 외부 시스템에 콜백 URL 전달
주의해야할 점
build_absolute_uri()는 호스트를 만들 때 요청의 Host 정보에 의존합니다(내부적으로 get_host()를 사용).
실제 요청이 들어온 url이 아닙니다. 대부분의 평범한 상황에서는 get_host()의 값과 실제 url도메인이 일치할 수도 있지만, Nginx 가 리버스 프록시 혹은 Django 미들웨어에서 개발자가 의도적으로 get_host() 값고 다른 tenant host를 사용하도록 로직을 만들 경우, {{ request.build_absolute_uri }} 의 값이 항상 실제 브라우저의 url과 일치한다고 볼 수는 없습니다.
따라서, nginx든 Django앱 내부에서든 어떠한 도메인관련 로직을 구현하셨다면, 예상과 다른 도메인/스킴으로 만들어질 수 있으니 배포 설정도 같이 점검하는 게 좋습니다.
결론 및 요약
- 템플릿에서 메뉴 active 처리 →
request.path - 서브패스 배포/프록시 환경까지 안정적으로 비교 →
request.path_info - 쿼리스트링까지 포함해서 “현재 페이지 그대로” →
request.get_full_path() - 외부로 나가는 완전한 링크(도메인 포함) →
request.build_absolute_uri()
관련글 보기: