Browse Source
Add subdomain routing middleware and admin URL configuration
Add subdomain routing middleware and admin URL configuration
- Implemented SubdomainRoutingMiddleware to route requests based on subdomains. - Created urls_admin.py for handling admin-related URLs and Swagger documentation. - Updated base settings to include the new middleware for subdomain handling.master
3 changed files with 170 additions and 0 deletions
@ -0,0 +1,106 @@ |
|||||
|
""" |
||||
|
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' |
||||
|
|
||||
|
|
||||
|
|
||||
@ -0,0 +1,62 @@ |
|||||
|
""" |
||||
|
URL configuration for Admin Subdomain (admin.imamjavad.nwhco.ir) |
||||
|
|
||||
|
This handles all admin-related URLs and Swagger/Redoc when accessed via the admin subdomain. |
||||
|
""" |
||||
|
from django.urls import path, include, re_path |
||||
|
from django.conf import settings |
||||
|
from django.conf.urls.static import static |
||||
|
from django.conf.urls.i18n import i18n_patterns |
||||
|
|
||||
|
from drf_yasg.views import get_schema_view |
||||
|
from drf_yasg import openapi |
||||
|
|
||||
|
from utils.admin import project_admin_site, dovoodi_admin_site, HomeView |
||||
|
from apps.api.views import CustomAPIDocumentationView, CustomSwaggerView, SwaggerTokenAuthView, clear_swagger_auth |
||||
|
from apps.api.permissions import IsAdminOrSwaggerToken |
||||
|
from apps.api.decorators import swagger_auth_required |
||||
|
|
||||
|
# Schema view for documentation |
||||
|
schema_view = get_schema_view( |
||||
|
openapi.Info( |
||||
|
title="Imam Javad API", |
||||
|
default_version='v1', |
||||
|
description="Comprehensive API documentation for the Imam Javad educational platform", |
||||
|
contact=openapi.Contact(email="contact@imamjavad.com"), |
||||
|
license=openapi.License(name="MIT License"), |
||||
|
), |
||||
|
public=False, |
||||
|
permission_classes=(IsAdminOrSwaggerToken,), |
||||
|
) |
||||
|
|
||||
|
# Swagger URL patterns |
||||
|
swagger_urlpatterns = [ |
||||
|
path('swagger-auth/', SwaggerTokenAuthView.as_view(), name='swagger-token-auth'), |
||||
|
path('swagger-auth/clear/', clear_swagger_auth, name='clear-swagger-auth'), |
||||
|
re_path(r'^swagger(?P<format>\.json|\.yaml)$', |
||||
|
swagger_auth_required(schema_view.without_ui(cache_timeout=0)), |
||||
|
name='schema-json'), |
||||
|
path('swagger/', CustomSwaggerView.as_view(), name='schema-swagger-ui'), |
||||
|
re_path(r'^redoc/$', |
||||
|
swagger_auth_required(schema_view.with_ui('redoc', cache_timeout=0)), |
||||
|
name='schema-redoc'), |
||||
|
] |
||||
|
|
||||
|
urlpatterns = [ |
||||
|
# Root redirect to admin |
||||
|
path("", HomeView.as_view(), name="home"), |
||||
|
path("i18n/", include("django.conf.urls.i18n")), |
||||
|
path('filer/', include('filer.urls')), |
||||
|
] |
||||
|
|
||||
|
# i18n admin + swagger patterns |
||||
|
urlpatterns += i18n_patterns( |
||||
|
path("imam-javad/admin/", project_admin_site.urls), |
||||
|
path("dovoodi/admin/", dovoodi_admin_site.urls), |
||||
|
path('docs/', CustomAPIDocumentationView.as_view(), name='docs-index'), |
||||
|
*swagger_urlpatterns, |
||||
|
path('filer/', include('filer.urls')), |
||||
|
) |
||||
|
|
||||
|
if settings.DEBUG: |
||||
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue