如何从Django模板中获取当前站点的域名?我试着在标签和过滤器中寻找,但没有什么。


当前回答

类似于用户panchicore的回复,这是我在一个非常简单的网站上所做的。 它提供了一些变量,并使它们在模板中可用。

SITE_URL将保存类似example.com的值 SITE_PROTOCOL将保存类似http或https的值 SITE_PROTOCOL_URL将包含http://example.com或https://example.com这样的值 SITE_PROTOCOL_RELATIVE_URL将包含类似//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
    }

settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    "module.context_processors.site",
    ....
 )

SITE_URL = 'example.com'

然后,在你的模板上,使用它们作为{{SITE_URL}}, {{SITE_PROTOCOL}}, {{SITE_PROTOCOL_URL}}和{{SITE_PROTOCOL_RELATIVE_URL}}

其他回答

类似于用户panchicore的回复,这是我在一个非常简单的网站上所做的。 它提供了一些变量,并使它们在模板中可用。

SITE_URL将保存类似example.com的值 SITE_PROTOCOL将保存类似http或https的值 SITE_PROTOCOL_URL将包含http://example.com或https://example.com这样的值 SITE_PROTOCOL_RELATIVE_URL将包含类似//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
    }

settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    "module.context_processors.site",
    ....
 )

SITE_URL = 'example.com'

然后,在你的模板上,使用它们作为{{SITE_URL}}, {{SITE_PROTOCOL}}, {{SITE_PROTOCOL_URL}}和{{SITE_PROTOCOL_RELATIVE_URL}}

你可以使用request.build_absolute_uri()

默认情况下,它将返回一个完整的路径。

但是如果你传入一个像这样的参数:

request.build_absolute_uri('/')

这将返回域名。

下面这些可以获得完整的url和部分url:

def myview(request):
    request.build_absolute_uri()
    # http://localhost:8000/admin/store/product/

    request.build_absolute_uri('/')
    # http://localhost:8000/

    request.build_absolute_uri('/')[:-1]
    # http://localhost:8000

    request.scheme
    # http

    request.META['HTTP_HOST']
    # localhost:8000

    request.path    
    # /admin/store/product/

{{请求。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 %}

我使用自定义模板标记。例如:<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

在模板中使用它,就像这样:

{% load site %}
{% current_domain %}