You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

106 lines
3.4 KiB

"""
Subdomain Routing Middleware
Routes requests to different URL configurations based on the subdomain.
This allows clean separation of admin, API, and docs URLs.
Subdomains:
- admin.imamjavad.nwhco.ir → config.urls_admin
- api.imamjavad.nwhco.ir → config.urls_api
- docs.imamjavad.nwhco.ir → config.urls_docs
- imamjavad.nwhco.ir → config.urls (main/frontend)
"""
from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
class SubdomainRoutingMiddleware(MiddlewareMixin):
"""
Middleware that sets the ROOT_URLCONF based on the request's subdomain.
"""
# Mapping of subdomain prefixes to URL configurations
SUBDOMAIN_URLCONFS = {
'admin': 'config.urls_admin', # Admin + Swagger/Redoc
}
# List of main domains (without subdomain routing)
MAIN_DOMAINS = [
'imamjavad.nwhco.ir',
'imamjavad.newhorizonco.uk',
'dovoodi.nwhco.ir',
'dovodi.newhorizonco.uk',
'localhost',
'127.0.0.1',
]
def process_request(self, request):
"""
Determine the subdomain and set the appropriate ROOT_URLCONF.
"""
# Get host from request (handles X-Forwarded-Host for proxied requests)
host = request.get_host().split(':')[0].lower()
# Check if this is a subdomain request
subdomain = self._extract_subdomain(host)
if subdomain and subdomain in self.SUBDOMAIN_URLCONFS:
# Set the URL configuration for this subdomain
request.urlconf = self.SUBDOMAIN_URLCONFS[subdomain]
# Store subdomain info for potential use in views
request.subdomain = subdomain
else:
# Use default URL configuration
request.subdomain = None
return None
def _extract_subdomain(self, host):
"""
Extract the subdomain from the host.
Examples:
- admin.imamjavad.nwhco.ir → 'admin'
- api.imamjavad.nwhco.ir → 'api'
- imamjavad.nwhco.ir → None
"""
# Check against main domains
for main_domain in self.MAIN_DOMAINS:
if host == main_domain:
return None
# Check if host is a subdomain of a main domain
if host.endswith('.' + main_domain):
# Extract subdomain part
subdomain = host[:-len('.' + main_domain)]
# Only return first-level subdomain
if '.' not in subdomain:
return subdomain
# Also check against ALLOWED_HOSTS for flexibility
for allowed_host in getattr(settings, 'ALLOWED_HOSTS', []):
if allowed_host.startswith('.'):
# Wildcard domain like .nwhco.ir
base_domain = allowed_host[1:]
if host.endswith(base_domain) and host != base_domain:
subdomain = host[:-len(base_domain)].rstrip('.')
if '.' not in subdomain:
return subdomain
return None
def get_subdomain(request):
"""
Utility function to get the current subdomain from request.
Can be used in views or templates.
"""
return getattr(request, 'subdomain', None)
def is_admin_subdomain(request):
"""Check if current request is on admin subdomain."""
return get_subdomain(request) == 'admin'