django-subdomains2 is a fork of the no longer managed django-subdomain repo.
Tested on Python 3.8, 3.9, 3.10 and Django 3.2, 4.0
pip install django-subdomains2-
Add
subdomains.middleware.SubdomainURLRoutingMiddlewareto yourMIDDLEWAREin your Django settings file. If you are usingdjango.middleware.common.CommonMiddleware, the subdomain middlware should come beforeCommonMiddlewareMIDDLEWARE = [ ... "subdomains.middleware.SubdomainURLRoutingMiddleware", "django.middleware.common.CommonMiddleware", ... ]
-
Configure the
SUBDOMAIN_URLCONFSdictionary in Django settings file.# This is the urlconf that will be used for any subdomain that is not # listed in "SUBDOMAIN_URLCONFS", or if the HTTP "Host" header does not # contain the correct domain. # If you're planning on using wildcard subdomains, this should correspond # to the urlconf that will be used for the wildcard subdomain. For example, # 'test.mysite.com' will load the ROOT_URLCONF, since it is not # defined in "SUBDOMAIN_URLCONFS". ROOT_URLCONF = "myproject.urls.frontend" # A dictionary of urlconf module paths, keyed by their subdomain. SUBDOMAIN_URLCONFS = { None: "myproject.urls.frontend", "www": "myproject.urls.frontend", "api": "myproject.urls.api", "admin": "myproject.urls.admin", }
-
Configure the
SUBDOMAIN_DOMAINin Django settings file.SUBDOMAIN_DOMAIN = "mysite.com" SUBDOMAIN_IGNORE_HOSTS = ["health-check"] # Optional, If you want to ignore the "health-check" host
Optional -
SUBDOMAIN_IGNORE_HOSTSAdd hosts toSUBDOMAIN_IGNORE_HOSTSif you need a list of hosts not to search for subdomains (which automatically uses the "None" value of SUBDOMAIN_URLCONFS) -
If you want to use the subdomain-based
{% url %}template tag, addsubdomainsto yourINSTALLED_APPS.
On each request, a subdomain attribute will be added to the request object. You can use this attribute to effect view logic, like in this example:
def user_profile(request):
try:
# Retrieve the user account associated with the current subdomain.
user = User.objects.get(username=request.subdomain)
except User.DoesNotExist:
# No user matches the current subdomain, so return a generic 404.
raise Http404Included is a subdomains.utils.reverse() function that responds similarly to django.core.urlresolvers.reverse(), but accepts optional subdomain and scheme arguments and does not allow a urlconf parameter.
If no subdomain argument is provided, the URL will be resolved relative to the SUBDOMAIN_URLCONFS[None] or ROOT_URLCONF, in order. The protocol scheme is the value of settings.DEFAULT_URL_SCHEME, or if unset, http:
>>> from subdomains.utils import reverse
>>> reverse('home')
'http://example.com/'
>>> reverse('user-profile', kwargs={'username': 'ted'})
'http://example.com/users/ted/'
>>> reverse('home', scheme='https')
'https://example.com/'For subdomains, the URL will be resolved relative to the SUBDOMAIN_URLCONFS[subdomain] value if it exists, otherwise falling back to the ROOT_URLCONF:
>>> from subdomains.utils import reverse
>>> reverse('home', subdomain='api')
'http://api.example.com/'
>>> reverse('home', subdomain='wildcard')
'http://wildcard.example.com/'
>>> reverse('login', subdomain='wildcard')
'http://wildcard.example.com/login/'If a URL cannot be resolved, a django.urls.exceptions.NoReverseMatch will be raised.
The subdomainurls template tag library contains a url tag that takes an optional subdomain argument as it’s first positional argument, or as named argument. The following are all valid invocations of the tag:
{% load subdomainurls %}
{% url 'home' %}
{% url 'home' 'subdomain' %}
{% url 'home' subdomain='subdomain' %}
{% url 'user-profile' username='ted' %}
{% url 'user-profile' subdomain='subdomain' username='ted' %}
If request is in the template context when rendering and no subdomain is provided, the URL will be attempt to be resolved by relative to the current subdomain. If no request is available, the URL will be resolved using the same rules as a call to subdomains.utils.reverse() without a subdomain argument value. An easy way to ensure this functionality is available is to add django.core.context_processors.request() is in your settings.TEMPLATES["OPTIONS"]["context_processors"] list.
tox
pip install build setuptools wheel
python -m build
twine upload dist/*