如何从Django模板中获取当前站点的域名?我试着在标签和过滤器中寻找,但没有什么。
当前回答
如果你使用“request”上下文处理器,并且正在使用Django sites框架,并且已经安装了Site中间件(即你的设置包括这些):
INSTALLED_APPS = [
...
"django.contrib.sites",
...
]
MIDDLEWARE = [
...
"django.contrib.sites.middleware.CurrentSiteMiddleware",
...
]
... 那么您将在模板中拥有可用的请求对象,并且它将包含对请求的当前Site的引用,即request. Site。然后你可以在模板中检索域:
{{request.site.domain}}
并附上网站名称:
{{request.site.name}}
其他回答
我发现了{{请求。Get_host}}方法。
{{请求。get_host}}在和ALLOWED_HOSTS设置(在Django 1.4.4中添加)一起使用时,可以防止HTTP主机头攻击。
注意{{request.META。HTTP_HOST}}没有相同的保护。查看文档:
ALLOWED_HOSTS A list of strings representing the host/domain names that this Django site can serve. This is a security measure to prevent HTTP Host header attacks, which are possible even under many seemingly-safe web server configurations. ... If the Host header (or X-Forwarded-Host if USE_X_FORWARDED_HOST is enabled) does not match any value in this list, the django.http.HttpRequest.get_host() method will raise SuspiciousOperation. ... This validation only applies via get_host(); if your code accesses the Host header directly from request.META you are bypassing this security protection.
至于在模板中使用请求,在Django 1.8中,模板渲染函数调用已经改变了,所以你不再需要直接处理RequestContext。
下面是如何渲染视图的模板,使用快捷函数render():
from django.shortcuts import render
def my_view(request):
...
return render(request, 'my_template.html', context)
下面是如何呈现一个电子邮件模板,IMO是更常见的情况下,你想要的主机值:
from django.template.loader import render_to_string
def my_view(request):
...
email_body = render_to_string(
'my_template.txt', context, request=request)
下面是一个在电子邮件模板中添加完整URL的示例;请求。Scheme应该获得HTTP或HTTPS,这取决于您使用的是什么:
Thanks for registering! Here's your activation link:
{{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
如果你使用“request”上下文处理器,并且正在使用Django sites框架,并且已经安装了Site中间件(即你的设置包括这些):
INSTALLED_APPS = [
...
"django.contrib.sites",
...
]
MIDDLEWARE = [
...
"django.contrib.sites.middleware.CurrentSiteMiddleware",
...
]
... 那么您将在模板中拥有可用的请求对象,并且它将包含对请求的当前Site的引用,即request. Site。然后你可以在模板中检索域:
{{request.site.domain}}
并附上网站名称:
{{request.site.name}}
正如@furins的回复中提到的,代理服务器可能存在问题。我在使用Apache和uWSGI - request时发现了这一点。Get_host或request。Build_absolute_uri将返回代理主机(127.0.0.1:9191…)。
然而,有人已经发布了一个有用的指南来解决这个问题:
https://ubuntu.com/blog/django-behind-a-proxy-fixing-absolute-urls
虽然这是一个相对较老的答案,但它仍然与django 3.2和python 3.9相关。
为了防止这个答案在未来消失,以下是它的要点:
settings.py
# Setup support for proxy headers
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
apache.conf
<VirtualHost *:443>
...
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
ProxyPass / http://10.0.0.3/
ProxyPassReverse / http://10.0.0.3/
...
</VirtualHost>
使用这些设置请求。Get_host和request。Build_absolute_uri引用客户端请求的主机,而不是代理主机。
我使用的上下文处理器的变化是:
from django.contrib.sites.shortcuts import get_current_site
from django.utils.functional import SimpleLazyObject
def site(request):
return {
'site': SimpleLazyObject(lambda: get_current_site(request)),
}
SimpleLazyObject包装器确保仅在模板实际使用站点对象时才发生DB调用。这将从管理页面中删除查询。它还缓存结果。
并将其包含在设置中:
TEMPLATE_CONTEXT_PROCESSORS = (
...
"module.context_processors.site",
....
)
在模板中,可以使用{{site。Domain}}获取当前域名。
编辑:也支持协议切换,使用:
def site(request):
site = SimpleLazyObject(lambda: get_current_site(request))
protocol = 'https' if request.is_secure() else 'http'
return {
'site': site,
'site_root': SimpleLazyObject(lambda: "{0}://{1}".format(protocol, site.domain)),
}
推荐文章
- pylab和pyplot的区别是什么?
- Argparse:确定使用了哪个子解析器
- django导入错误-没有core.management模块
- 在芹菜中检索队列中的任务列表
- 使用beautifulsoup提取属性值
- 如何禁用标准错误流的日志记录?
- 用Matplotlib在Python中绘制时间
- 类中的Python装饰器
- 在Python中锁定文件
- 得到熊猫栏目的总数
- 从pandas DataFrame中删除名称包含特定字符串的列
- Mock vs MagicMock
- 如何阅读一个。xlsx文件使用熊猫库在iPython?
- 如何访问熊猫组由数据帧按键
- Pandas和NumPy+SciPy在Python中的区别是什么?