在没有找到所需内容之后,我采用了以下解决方案。我放弃了 request.urlconf
映射,转而重写 request.path_info
。如果有人遇到这个问题,我在此发布我的解决方案。
第一步,将以下中间件添加到您的项目中:
class SubdomainMiddleware:
"""Subdomain for Django"""
def process_request(self, request):
domain_parts = request.get_host().lower().replace('www.', '').split('.example.com', 1)
if len(domain_parts) > 1 and domain_parts[0]:
subdomain = domain_parts[0]
else:
subdomain = None
if subdomain:
if request.path_info[-1] != '/':
request.path_info += '/'
request.path_info = '/%s%s' % (subdomain, request.path_info)
接下来,请添加以下代码,覆盖
reverse
函数:
from django.conf import settings
from django.core import urlresolvers
_reverse = urlresolvers.reverse
def reverse(*args, **kwargs):
if args[0].startswith('http'):
return args[0]
if '/' not in args[0]:
url = _reverse(*args, **kwargs)
else:
url = args[0]
parts = url.strip('/').split('/', 1)
subdomain = parts[0]
path = parts[1] if len(parts) > 1 else ''
protocol = 'http://' if settings.DEBUG else 'https://'
return '%s%s%s/%s' % (protocol, subdomain, '.example.com', path)
urlresolvers.reverse = reverse
我把它放在同一个文件中自定义的中间件所在的位置。
就这样!
据我所知和测试,一切正常:反转、重定向、模板 {% url %} 标签等。
注意:
在此代码中,我做了三个假设:
- 域名为
example.com
。根据您的需要更改它,将其放置在 settings.py
中,或者使用适合您的任何方法。
- 子域映射到子文件夹。例如,
sub.example.com
将被转换为 example.com/sub
。
- 我的站点在任何地方都使用 SSL。因此,我只需在自定义的
reverse
函数中检查 settings.DEBUG
值,以确定它应该使用 http
还是 https
。
希望对您有所帮助。