This is a very handy Django package that I’ve used in a couple of projects. Essentially django-hosts let you serve different parts of your application under different subdomains. For example, let’s say we have a Django application deployed on www.example.com. With this app you can serve an e-commerce under shop.example.com and the help center under help.example.com. And in the end, it’s just a single Django website.
It can also be used to host user spaces, with a wildcard, where your users could get their own subdomain like vitor.example.com or erica.example.com. But that require a few tweaks in the DNS configuration.
A small caveat of developing with django-hosts is that you will need to do some configurations in your local machine, which can differ if you are using Windows, Linux or Mac.
Installation
Install it with pip:
pip install django-hosts
Add the django_hosts
to the INSTALLED_APPS
:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_hosts',
'core',
]
Add the HostsRequestMiddleware
in the beginning of the MIDDLEWARE
and HostsResponseMiddleware
in the end of the
MIDDLEWARE
:
MIDDLEWARE = [
'django_hosts.middleware.HostsRequestMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django_hosts.middleware.HostsResponseMiddleware',
]
Still in the settings.py, add the following configuration variables:
ROOT_HOSTCONF = 'mysite.hosts' # Change `mysite` to the name of your project
DEFAULT_HOST = 'www' # Name of the default host, we will create it in the next steps
Create a file named hosts.py right next to the urls.py:
mysite/
|-- __init__.py
|-- hosts.py # <-- The `ROOT_HOSTCONF` refers to this file
|-- settings.py
|-- urls.py
+-- wsgi.py
mysite/hosts.py
from django.conf import settings
from django_hosts import patterns, host
host_patterns = patterns('',
host(r'www', settings.ROOT_URLCONF, name='www'), # <-- The `name` we used to in the `DEFAULT_HOST` setting
)
Usage
Let’s create an app named help to illustrate the usage of the django-hosts:
django-admin startapp help
Then inside of the new app, we create a urls.py module:
help/urls.py
from django.conf.urls import url, include
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^articles/$', views.articles, name='articles'),
url(r'^articles/(?P<pk>\d+)/$', views.article_details, name='article_details'),
]
Now we update the mysite/hosts, which is our ROOT_HOSTCONF
:
mysite/hosts.py
from django.conf import settings
from django_hosts import patterns, host
host_patterns = patterns('',
host(r'www', settings.ROOT_URLCONF, name='www'),
host(r'help', 'help.urls', name='help'),
)
Testing Locally
In order to test it locally, you will need to setup a local DNS host.
On Linux and Mac, the file is located in the path /etc/hosts
. For Windows it should be somewhere in
%SystemRoot%\system32\drivers\etc\hosts
.
hosts
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
127.0.0.1 www.mysite.local
127.0.0.1 help.mysite.local


Templates
Now instead of using the {% url 'home' %}
notation, you can load the django-hosts template tags:
{% load hosts %}
<a href="{% host_url 'home' host 'www' %}">Homepage</a>
<a href="{% host_url 'articles' host 'help' %}">Help Articles</a>
Reverse
The django-hosts extends Django’s default reverse function so you can pass an extra argument host:
from django.shortcuts import render
from django_hosts.resolvers import reverse
def homepage(request):
homepage_url = reverse('homepage', host='www')
return render(request, 'homepage.html', {'homepage_url': homepage_url})
Further Reading
You can learn more by reading the Official Documentation or browsing the code on GitHub.