Car*_*yer 96
如果你想要实际的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
Run Code Online (Sandbox Code Playgroud)
如果要使用它,必须自己将current_site对象放入模板上下文中.如果您在整个地方使用它,您可以将其打包在模板上下文处理器中.
dan*_*gge 77
我发现了这种{{ request.get_host }}
方法.
小智 61
我想你想要的是访问请求上下文,请参阅RequestContext.
pan*_*ore 58
作为Carl Meyer的补充,您可以制作这样的上下文处理器:
from django.conf import settings
def site(request):
return {'SITE_URL': settings.SITE_URL}
Run Code Online (Sandbox Code Playgroud)
SITE_URL = 'http://google.com' # this will reduce the Sites framework db call.
Run Code Online (Sandbox Code Playgroud)
TEMPLATE_CONTEXT_PROCESSORS = (
...
"module.context_processors.site",
....
)
Run Code Online (Sandbox Code Playgroud)
如果要在上下文处理器中处理子域或SSL,您可以编写自己的rutine.
vdb*_*oor 24
我使用的上下文处理器的变化是:
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)),
}
Run Code Online (Sandbox Code Playgroud)
该SimpleLazyObject
包装可以确保DB调用只有当模板实际使用情况site
的对象.这将从管理页面中删除查询.它还缓存了结果.
并将其包含在以下设置中:
TEMPLATE_CONTEXT_PROCESSORS = (
...
"module.context_processors.site",
....
)
Run Code Online (Sandbox Code Playgroud)
在模板中,您可以使用{{ 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)),
}
Run Code Online (Sandbox Code Playgroud)
mis*_*rte 18
我知道这个问题很老,但我偶然发现它寻找一种获取当前域名的pythonic方法.
def myview(request):
domain = request.build_absolute_uri('/')[:-1]
# that will build the complete domain: http://foobar.com
Run Code Online (Sandbox Code Playgroud)
Edw*_*ell 17
快速简单,但不适合生产:
(在视图中)
request.scheme # http or https
request.META['HTTP_HOST'] # example.com
request.path # /some/content/1/
Run Code Online (Sandbox Code Playgroud)
(在模板中)
{{ request.scheme }} :// {{ request.META.HTTP_HOST }} {{ request.path }}
Run Code Online (Sandbox Code Playgroud)
一定要使用RequestContext,如果你使用的是渲染.
不信任request.META['HTTP_HOST']
生产:该信息来自浏览器.相反,请使用@ CarlMeyer的答案
S. *_*rby 13
{{ 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)
Run Code Online (Sandbox Code Playgroud)
以下是如何为电子邮件呈现模板,IMO是您需要主机值的更常见情况:
from django.template.loader import render_to_string
def my_view(request):
...
email_body = render_to_string(
'my_template.txt', context, request=request)
Run Code Online (Sandbox Code Playgroud)
以下是在电子邮件模板中添加完整网址的示例; request.scheme应该得到http
或https
取决于你使用的是什么:
Thanks for registering! Here's your activation link:
{{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
Run Code Online (Sandbox Code Playgroud)
If you use the "request" context processor, and are using the Django sites framework, and have the Site middleware installed (i.e. your settings include these):
INSTALLED_APPS = [
...
"django.contrib.sites",
...
]
MIDDLEWARE = [
...
"django.contrib.sites.middleware.CurrentSiteMiddleware",
...
]
Run Code Online (Sandbox Code Playgroud)
... then you will have the request
object available in templates, and it will contain a reference to the current Site
for the request as request.site
. You can then retrieve the domain in a template with:
{{request.site.domain}}
Run Code Online (Sandbox Code Playgroud)
and the site name with:
{{request.site.name}}
Run Code Online (Sandbox Code Playgroud)
我使用自定义模板标签.添加到例如<your_app>/templatetags/site.py
:
# -*- 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
Run Code Online (Sandbox Code Playgroud)
在这样的模板中使用它:
{% load site %}
{% current_domain %}
Run Code Online (Sandbox Code Playgroud)
类似于用户 panchicore 的回复,这是我在一个非常简单的网站上所做的。它提供了一些变量并使它们在模板上可用。
SITE_URL
将持有一个值 likeexample.com
SITE_PROTOCOL
将持有一个值 likehttp
或https
SITE_PROTOCOL_URL
将持有一个值 likehttp://example.com
或https://example.com
SITE_PROTOCOL_RELATIVE_URL
将持有一个值 like //example.com
。
模块/context_processors.py
from django.conf import settings
def site(request):
SITE_PROTOCOL_RELATIVE_URL = '//' + settings.SITE_URL
SITE_PROTOCOL = 'http'
if request.is_secure():
SITE_PROTOCOL = 'https'
SITE_PROTOCOL_URL = SITE_PROTOCOL + '://' + settings.SITE_URL
return {
'SITE_URL': settings.SITE_URL,
'SITE_PROTOCOL': SITE_PROTOCOL,
'SITE_PROTOCOL_URL': SITE_PROTOCOL_URL,
'SITE_PROTOCOL_RELATIVE_URL': SITE_PROTOCOL_RELATIVE_URL
}
Run Code Online (Sandbox Code Playgroud)
设置.py
TEMPLATE_CONTEXT_PROCESSORS = (
...
"module.context_processors.site",
....
)
SITE_URL = 'example.com'
Run Code Online (Sandbox Code Playgroud)
然后,在你的模板,把它们作为{{ SITE_URL }}
,{{ SITE_PROTOCOL }}
,{{ SITE_PROTOCOL_URL }}
和{{ SITE_PROTOCOL_RELATIVE_URL }}
小智 6
您可以使用request.build_absolute_uri()
默认情况下,它将返回完整路径。
但如果你传入这样的参数:
request.build_absolute_uri('/')
Run Code Online (Sandbox Code Playgroud)
这将返回域名。