gpt4 book ai didi

django-templates - Django - URL 模板标签与子域断开

转载 作者:行者123 更新时间:2023-12-04 08:30:29 25 4
gpt4 key购买 nike

我使用自定义中间件将子域映射到应用程序的 urls.py,方法是将相关的 urls.py 分配给 request.urlconf多变的。

这工作正常,除了 {% url %} 模板标签。
我得到了一个 NoReverseMatch 并且不知道为什么。
调试页面显示 reverse 函数在 view_name 参数中接收到一个值,因此它应该可以工作。

模板中的每个 {% url %} 标签都会发生这种情况。
如果我切换到类似文件夹的 url(例如 myproject.com/sub,而不是 sub.myproject.com),标签工作正常。

非常感谢任何关于为什么会发生这种情况以及如何解决这个问题的想法。

最佳答案

好吧,在没有找到我需要的东西之后,我得出了以下解决方案。我丢弃了 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
  • 我的网站在任何地方都使用 SSL。所以我只是检查自定义 reverse 函数中的 settings.DEBUG 值,看看它是否应该使用 httphttps

希望对您有所帮助。

关于django-templates - Django - URL 模板标签与子域断开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16511716/

25 4 0