如何从Django模板中获取当前站点的域名?我试过看标签和过滤器,但没有.
如果你想要实际的HTTP Host标题,请参阅Daniel Roseman对@ Phsiao的回答的评论.另一种方法是,如果您使用的是contrib.sites框架,则可以在数据库中为站点设置规范域名(将请求域映射到具有正确SITE_ID的设置文件是您必须自己通过网络服务器设置).在这种情况下,你正在寻找:
from django.contrib.sites.models import Site current_site = Site.objects.get_current() current_site.domain
如果要使用它,必须自己将current_site对象放入模板上下文中.如果您在整个地方使用它,您可以将其打包在模板上下文处理器中.
我发现了这种{{ request.get_host }}
方法.
我想你想要的是访问请求上下文,请参阅RequestContext.
作为Carl Meyer的补充,您可以制作这样的上下文处理器:
from django.conf import settings def site(request): return {'SITE_URL': settings.SITE_URL}
SITE_URL = 'http://google.com' # this will reduce the Sites framework db call.
TEMPLATE_CONTEXT_PROCESSORS = ( ... "module.context_processors.site", .... )
如果要在上下文处理器中处理子域或SSL,您可以编写自己的rutine.
我使用的上下文处理器的变化是:
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调用只有当模板实际使用情况site
的对象.这将从管理页面中删除查询.它还缓存了结果.
并将其包含在以下设置中:
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)), }
我知道这个问题很老,但我偶然发现它寻找一种获取当前域名的pythonic方法.
def myview(request): domain = request.build_absolute_uri('/')[:-1] # that will build the complete domain: http://foobar.com
快速简单,但不适合生产:
(在视图中)
request.scheme # http or https request.META['HTTP_HOST'] # example.com request.path # /some/content/1/
(在模板中)
{{ request.scheme }} :// {{ request.META.HTTP_HOST }} {{ request.path }}
一定要使用RequestContext,如果你使用的是渲染.
不信任request.META['HTTP_HOST']
生产:该信息来自浏览器.相反,请使用@ CarlMeyer的答案
{{ request.get_host }}
当与ALLOWED_HOSTS
设置一起使用时,应该防止HTTP Host头攻击(在Django 1.4.4中添加).
请注意,{{ request.META.HTTP_HOST }}
没有相同的保护.查看文档:
ALLOWED_HOSTS
表示此Django站点可以提供的主机/域名的字符串列表.这是一种防止HTTP主机头攻击的安全措施,即使在许多看似安全的Web服务器配置下也是如此.
...如果
Host
标题(或者X-Forwarded-Host
如果USE_X_FORWARDED_HOST
已启用)与此列表中的任何值都不匹配,则该django.http.HttpRequest.get_host()
方法将引发SuspiciousOperation
.......此验证仅适用于
get_host()
; 如果您的代码直接从request.META
您访问Host标头,则绕过此安全保护.
至于request
在模板中使用,模板渲染函数调用在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)
以下是在电子邮件模板中添加完整网址的示例; request.scheme应该得到http
或https
取决于你使用的是什么:
Thanks for registering! Here's your activation link: {{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
我使用自定义模板标签.添加到例如
:
# -*- coding: utf-8 -*- from django import template from django.contrib.sites.models import Site register = template.Library() @register.simple_tag def current_domain(): return 'http://%s' % Site.objects.get_current().domain
在这样的模板中使用它:
{% load site %} {% current_domain %}