Extracting URLs in Django Templates: request.path vs path_info vs get_full_path vs build_absolute_uri
Often you need the current URL in a Django template.
- Highlighting the active navigation item
- Redirecting back to the original page after login (
next) - Generating canonical URLs or share links
- Creating a link that points to the exact current page, including query strings
Besides {{ request.path }}, Django has a few similar attributes that can be confusing. Today we’ll cleanly compare the four most common ones:
request.pathrequest.path_inforequest.get_full_path()request.build_absolute_uri()
Where does {{ request }} come from?
If you see {{ request }} in a template, the request context processor is enabled.
django.template.context_processors.requestinjects therequestobject into the template context.- It is activated when added to
TEMPLATES→OPTIONS['context_processors'].
Django includes this processor by default, so you rarely need to change anything. The request object itself is an HttpRequest (actually a WSGI/ASGI subclass) created by Django when a request arrives and passed to the view. It contains attributes like path and path_info.

Quick Takeaway: How to remember the four attributes
path– Domain‑less path onlypath_info– The real path the app sees (excluding any script prefix)get_full_path()–pathplus the query stringbuild_absolute_uri()– Full URL: scheme, host, path, and query string
Let’s dive into each one.
1) request.path: Path without the domain
request.path returns the request path without scheme or host. Example:
/music/bands/the_beatles/
When is it useful?
- Simple comparisons for active menu items
django
{% if request.path == "/settings/" %}active{% endif %}
* Prefix checks like “which category is this page?”
django
{% if request.path|slice:":5" == "/api/" %}...{% endif %}
2) request.path_info: The stable path in deployment environments
The key point from the Django docs is:
- Some server configurations split the URL into a script prefix (
SCRIPT_NAME) and path info. path_infoalways contains the path info part, making it less dependent on the environment.
In practice, if your app is mounted under a prefix like /app (reverse proxy, sub-path deployment, etc.), path and path_info can differ.
When is it useful?
- When you need the app‑relative path in a sub‑path deployment (e.g.,
/app/). - When the prefix may change between test and production.
On a single‑domain root (
/),pathandpath_infoare identical, so the difference is often unnoticed until the environment changes.
3) request.get_full_path(): Path plus query string
get_full_path() returns the path plus the query string. Example:
/music/bands/the_beatles/?print=true
When is it useful?
- When you need a link that points to the exact current page for sharing, refreshing, or back‑navigation.
django
<a href="{{ request.get_full_path }}">Refresh link</a>
* When constructing a next parameter after login or permission checks.
django
<a href="/login/?next={{ request.get_full_path|urlencode }}">Login</a>
Django also offers
get_full_path_info(), which is based onpath_info. It’s not covered here but worth knowing.
4) request.build_absolute_uri(): Full absolute URL with scheme and host
build_absolute_uri() builds an absolute URI from the current request.
Typical output:
https://example.com/music/bands/the_beatles/?print=true
When is it useful?
- Email or messenger share links that require a full domain.
- Canonical URLs,
og:urlmeta tags. - Callback URLs for external systems.
Things to watch out for
build_absolute_uri() uses the host from the request (via get_host()), so it may not match the exact URL the browser used.In many cases the host matches, but if you’re behind Nginx reverse proxy or have custom tenant logic, the generated URL may differ from what the user sees. Always verify your deployment settings when using this method.
Summary
- Active menu in templates →
request.path - Stable comparison in sub‑path deployments →
request.path_info - Include query string for “current page” links →
request.get_full_path() - Full external link with domain →
request.build_absolute_uri()
Related posts: