Extracting URLs in Django Templates: request.path vs path_info vs get_full_path vs build_absolute_uri
Often you need the current URL inside a Django template.
\n- \n
- Highlighting the active navigation item \n
- Redirecting back to the original page after login (
next) \n - Generating canonical URLs or share links \n
- Creating a link that points to the exact current page, including query strings \n
Besides {{ request.path }}, there are several similar attributes that can be confusing. Today we’ll cleanly compare the four most common ones:
- \n
request.path\nrequest.path_info\nrequest.get_full_path()\nrequest.build_absolute_uri()\n
\n
Where does {{ request }} come from?
\nSeeing {{ request }} in a template means the request context processor is enabled.
- \n
django.template.context_processors.requestinjects therequestobject into the template context. \n- It is activated when added to
TEMPLATES→OPTIONS[\'context_processors\']. \n
Django ships with this processor pre‑configured, so developers rarely need to touch it. 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.

\n
Quick Takeaway: How to remember the four attributes
\n- \n
path– Domain‑less path only \npath_info– The real path the app sees (excluding any script prefix) \nget_full_path()–pathplus the query string \nbuild_absolute_uri()– Full URL: scheme, host, path, and query string \n
Let’s dive into each one.
\n\n
1) request.path: Path without the domain
\nrequest.path returns the request path without scheme or host. Example:
- \n
/music/bands/the_beatles/\n
When is it useful?
\n- \n
- Simple comparisons for active menu items \n
django\n {% if request.path == "/settings/" %}active{% endif %}\n* Prefix checks like “which category is this page?”
django\n {% if request.path|slice:":5" == "/api/" %}...{% endif %}
\n
2) request.path_info: The stable path in deployment environments
\nThe key point in the Django docs is:
\n- \n
- Some server configurations split the URL into a script prefix (
SCRIPT_NAME) and path info. \n path_infoalways contains the path info part, making it less dependent on the environment. \n
In practice, when 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?
\n- \n
- When you need the app‑relative path in a sub‑path deployment (e.g.,
/app/). \n - When the prefix may change between test and production. \n
\n\nOn a single‑domain root (
\n/),pathandpath_infoare identical, so the difference is often unnoticed until the environment changes.
\n
3) request.get_full_path(): Path plus query string
\nget_full_path() returns the path plus the query string. Example:
- \n
/music/bands/the_beatles/?print=true\n
When is it useful?
\n- \n
- When you need a link that points to the exact current page for sharing, refreshing, or back‑navigation. \n
django\n <a href="{{ request.get_full_path }}">Refresh link</a>\n* When constructing a next parameter after login or permission checks.
django\n <a href="/login/?next={{ request.get_full_path|urlencode }}">Login</a>
\n\nDjango also offers
\nget_full_path_info(), which is based onpath_info. It’s not covered here but worth knowing.
\n
4) request.build_absolute_uri(): Full absolute URL with scheme and host
\nbuild_absolute_uri() builds an absolute URI from the current request.
Typical output:
\n- \n
https://example.com/music/bands/the_beatles/?print=true\n
When is it useful?
\n- \n
- Email or messenger share links that require a full domain. \n
- Canonical URLs,
og:urlmeta tags. \n - Callback URLs for external systems. \n
Things to watch out for
\nbuild_absolute_uri() relies on the request’s host information (via get_host()). It does not reflect the actual 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.
\n
Summary
\n- \n
- Active menu in templates →
request.path\n - Stable comparison in sub‑path deployments →
request.path_info\n - Include query string for “current page” links →
request.get_full_path()\n - Full external link with domain →
request.build_absolute_uri()\n
\n
Related posts:
\n', '/media/editor_temp/6/c112847e-a9ca-4d58-9a3f-076a20bfbef7.png')