Host-based URL routing and host-aware reversing for Django, with zero call-site changes
Project description
django-hostmap
Host-based URL routing and host-aware reversing for Django, with zero call-site changes.
django-hostmap routes requests to different URLconfs by host (subdomain or
full domain) and makes URL reversing host-aware without changing a single
call site: the stock reverse(), reverse_lazy() and {% url %} keep
working everywhere, including inside third-party apps. Links within the
current host stay path-relative, exactly as Django produces them; links to
views on another host come back as absolute URLs. Configuration is one
declarative host map in settings plus one middleware.
It is the ecosystem's replacement for django-hosts, whose parallel reverse
API forces invasive changes across templates and Python code and cannot fix
third-party apps that call django.urls.reverse().
Installation
pip install django-hostmap
INSTALLED_APPS = [
# ...
"hostmap",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"hostmap.middleware.HostmapMiddleware", # before CommonMiddleware
"django.middleware.common.CommonMiddleware",
# ...
]
ROOT_URLCONF remains required (Django needs it at startup) and should point
at the default entry's URLconf (hostmap.W003 warns on mismatch).
The host map
HOSTMAP = {
"www": {"subdomain": "www", "urlconf": "config.urls.www"},
"api": {"subdomain": "api", "urlconf": "config.urls.api"},
"apex": {"host": "example.com", "redirect_to": "www"},
}
HOSTMAP_PARENT_DOMAIN = "example.com"
HOSTMAP_DEFAULT = "www"
With www active:
| Call | Returns |
|---|---|
reverse("blog:index") |
/blog/ (byte-identical to stock Django) |
reverse("api:user-detail", args=[7]) |
https://api.example.com/users/7/ |
{% url "api:user-detail" 7 %} |
the absolute URL, no template changes |
Same-host links stay relative; cross-host links come back absolute. Nothing at the call site changes.
Settings
| Setting | Default | Description |
|---|---|---|
HOSTMAP |
{} |
The host map. Empty map disables all behaviour |
HOSTMAP_PARENT_DOMAIN |
"" |
Domain joined to subdomain entries |
HOSTMAP_DEFAULT |
"" |
Entry for unmatched hosts and out-of-request reversing |
HOSTMAP_PATCH_REVERSE |
True |
Make stock reverse() / {% url %} host-aware |
HOSTMAP_SCHEME |
"https" |
Scheme for cross-host absolute URLs |
HOSTMAP_PORT |
"" |
Port appended to all generated hosts |
HOSTMAP_UNMATCHED |
"default" |
"default" routes unmatched hosts to the default entry; "reject" returns 404 |
HOSTMAP_REDIRECT_PERMANENT |
True |
redirect_to entries use 301, else 302 |
Explicit API
For code that needs an absolute URL regardless of the active host (emails, Celery tasks, API payloads, webhooks):
from hostmap.urls import reverse, build_absolute_uri, use_host
build_absolute_uri("api:user-detail", args=[7]) # always absolute
with use_host("api"):
reverse("user-detail", args=[7]) # api active
with use_host(host="acme.example.com"): # a wildcard host
reverse("dashboard")
Development story
Modern browsers resolve *.localhost to loopback (RFC 6761), so the whole
map works locally with no /etc/hosts edits:
HOSTMAP_PARENT_DOMAIN = "localhost"
HOSTMAP_SCHEME = "http"
HOSTMAP_PORT = "8000"
ALLOWED_HOSTS = [".localhost"]
Behind a proxy
Host routing is only as good as the Host header that reaches Django. Behind a
reverse proxy, either the proxy passes Host through unchanged or the
deployment sets USE_X_FORWARDED_HOST = True with the proxy sending
X-Forwarded-Host. Misrouted hosts behind nginx are otherwise the first
support issue.
Escape hatch
HOSTMAP_PATCH_REVERSE = False degrades cleanly to routing-only: the stock
reverse() is left untouched (cross-host links regress to paths), routing
keeps working, and the explicit API still works. Set it if a Django upgrade
lands before a compatible django-hostmap release; the startup self-test and
hostmap.W004 warn before anything breaks.
Diagnostics
manage.py hostmap # print the resolved map for the current settings
Licence
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_hostmap-0.1.1.tar.gz.
File metadata
- Download URL: django_hostmap-0.1.1.tar.gz
- Upload date:
- Size: 25.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b4b3328381681a24971d769233a79fbb077ccddc3bcdefbb7f7456e704578cf
|
|
| MD5 |
362d0476316c84380386e47bf15ea5b6
|
|
| BLAKE2b-256 |
0d0af2ed3bc01f6d067eb38940fa8b98132f3cc49ea0874629f2706534cd4c1e
|
Provenance
The following attestation bundles were made for django_hostmap-0.1.1.tar.gz:
Publisher:
publish.yml on icvoss/django-hostmap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_hostmap-0.1.1.tar.gz -
Subject digest:
1b4b3328381681a24971d769233a79fbb077ccddc3bcdefbb7f7456e704578cf - Sigstore transparency entry: 2152092296
- Sigstore integration time:
-
Permalink:
icvoss/django-hostmap@c300be808cf6e5eba92a7bd48eec0a0aafc6c7cd -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/icvoss
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c300be808cf6e5eba92a7bd48eec0a0aafc6c7cd -
Trigger Event:
push
-
Statement type:
File details
Details for the file django_hostmap-0.1.1-py3-none-any.whl.
File metadata
- Download URL: django_hostmap-0.1.1-py3-none-any.whl
- Upload date:
- Size: 22.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44eccc09d8de73c0a57ce52f6e507d2825cbbbcb4209a2466133955175dd27e3
|
|
| MD5 |
8784da55bb3ddbbd483bcfb1ba10a6e0
|
|
| BLAKE2b-256 |
1103a0e90619b4ef1cbbf3d3107b83dad18ea3b17a4f54064b5e8e315a79b4c2
|
Provenance
The following attestation bundles were made for django_hostmap-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on icvoss/django-hostmap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_hostmap-0.1.1-py3-none-any.whl -
Subject digest:
44eccc09d8de73c0a57ce52f6e507d2825cbbbcb4209a2466133955175dd27e3 - Sigstore transparency entry: 2152092408
- Sigstore integration time:
-
Permalink:
icvoss/django-hostmap@c300be808cf6e5eba92a7bd48eec0a0aafc6c7cd -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/icvoss
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c300be808cf6e5eba92a7bd48eec0a0aafc6c7cd -
Trigger Event:
push
-
Statement type: