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.path
  • request.path_info
  • request.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.request injects the request object into the template context.
  • It is activated when added to TEMPLATESOPTIONS['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.

Django the magician pulling tools out of a hat


Quick Takeaway: How to remember the four attributes

  • pathDomain‑less path only
  • path_infoThe real path the app sees (excluding any script prefix)
  • get_full_path()path plus the query string
  • build_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_info always 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 (/), path and path_info are 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 on path_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:url meta 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 templatesrequest.path
  • Stable comparison in sub‑path deploymentsrequest.path_info
  • Include query string for “current page” linksrequest.get_full_path()
  • Full external link with domainrequest.build_absolute_uri()

Related posts: