ICVOSS DJANGO PACKAGE REGISTRY

The package index django-hostmap Route a subdomain to its own URLconf

Route a subdomain to its own URLconf

Documentation

Goal

Add a new host to HOSTMAP so requests to a given subdomain (or full domain) are routed to their own URLconf.

Prerequisites

Steps

1. Decide subdomain or host

Each HOSTMAP entry sets exactly one of subdomain or host (hostmap.E002 fails startup otherwise):

Key Use when Example
subdomain The host is <label>.<HOSTMAP_PARENT_DOMAIN> "api" joined to example.com gives api.example.com
host The host is a full domain unrelated to the parent domain, or the bare parent domain itself "app.example.co.uk", or "example.com" for the apex

A subdomain of "" means the parent domain itself (equivalent to host: "<parent>"); a subdomain of "*" is a wildcard, covered in use wildcard subdomains.

2. Add the entry

# settings.py
HOSTMAP = {
    "www": {"subdomain": "www", "urlconf": "config.urls.www"},
    "api": {"subdomain": "api", "urlconf": "config.urls.api"},
    "shop": {"host": "shop.example.co.uk", "urlconf": "config.urls.shop"},
}
HOSTMAP_PARENT_DOMAIN = "example.com"
HOSTMAP_DEFAULT = "www"

shop above is a host entry: it does not live under HOSTMAP_PARENT_DOMAIN at all, so subdomain would not express it.

3. Point the entry at a real, importable URLconf

Each entry's urlconf is a dotted module path, exactly like ROOT_URLCONF. It must be a plain Python module containing urlpatterns; hostmap does not require anything special of it.

# config/urls/shop.py
from django.urls import path

from shop import views

urlpatterns = [
    path("", views.storefront, name="storefront"),
]

An unimportable urlconf value fails startup as hostmap.E006, naming the import error.

4. Confirm ALLOWED_HOSTS and ROOT_URLCONF

ALLOWED_HOSTS must cover every mapped host, or Django rejects the request before hostmap ever sees it (hostmap.W001 warns, but does not fail startup, if a host is missing).

ALLOWED_HOSTS = ["www.example.com", "api.example.com", "shop.example.co.uk"]

ROOT_URLCONF should point at the default entry's URLconf (hostmap.W003 warns otherwise), since Django needs ROOT_URLCONF at startup regardless of hostmap.

Verify it worked

python manage.py check
python manage.py hostmap

manage.py check should report no hostmap.E0xx errors. manage.py hostmap should list the new entry with its resolved host and URLconf:

shop
    host:     shop.example.co.uk
    urlconf:  config.urls.shop

Then hit it directly:

curl -H "Host: shop.example.co.uk" http://localhost:8000/

Common pitfalls