我使用自定义中间件将子域映射到应用程序“urls.py
”,方法是将相关的urls.py
分配给request.urlconf
变量。
除了{% url %}
模板标记外,此方法正常
我得到了NoReverseMatch
并且无法找出原因
调试页面显示reverse
函数在view_name
参数中收到一个值,因此它应该可以工作。
模板中的每个 {% url %}
标记都会发生这种情况
如果我切换到类似文件夹的网址(例如myproject.com/sub
,而不是sub.myproject.com
),则代码可以正常工作。
对于为什么会发生这种情况以及如何解决这个问题的任何想法都非常感激。
答案 0 :(得分:1)
好吧,在找不到我需要的东西之后,我找到了以下解决方案。
我放弃了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):
# In case reversing a full url
if args[0].startswith('http'):
return args[0]
# In case reversing a url name
if '/' not in args[0]:
url = _reverse(*args, **kwargs)
else:
# In case reversing a url path
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
。settings.DEBUG
函数中的reverse
值,看看它是否应使用http
或https
。 希望它有所帮助。