""" 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'