Как я могу получить доменное имя моего сайта в шаблон Django?

Как получить доменное имя моего текущего сайта из шаблона Django? Я пробовал искать в теге и фильтрах, но ничего там нет.

13 ответов


Я думаю, что вы хотите иметь доступ к контексту запроса, см. RequestContext.


Если вы хотите фактический заголовок Хоста HTTP, см. комментарий Даниэля Розмана к ответу @Phsiao. Другая альтернатива - если вы используете contrib.база сайтов, вы можете установить каноническое доменное имя для сайта в базе данных (сопоставление домена запроса с файлом настроек с правильным SITE_ID-это то, что вы должны сделать сами через настройку веб-сервера). В этом случае вы ищете:

from django.contrib.sites.models import Site

current_site = Site.objects.get_current()
current_site.domain

вам нужно будет поместить объект current_site в контекст шаблона сам, если вы хотите его использовать. Если вы используете его повсюду, вы можете упаковать его в обработчике контекста шаблона.


Я обнаружил {{ request.get_host }} метод.


дополняя Карла Мейера, вы можете сделать контекстный процессор следующим образом:

module.context_processors.py

from django.conf import settings

def site(request):
    return {'SITE_URL': settings.SITE_URL}

местные settings.py

SITE_URL = 'http://google.com' # this will reduce the Sites framework db call.

settings.py

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

шаблоны, возвращающие экземпляр контекста URL-адрес сайта {{ SITE_URL }}

вы можете написать свой собственный рутин, если хотите обрабатывать поддомены или SSL в контекстном процессоре.


вариация контекстного процессора, который я использую:

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 wrapper гарантирует, что вызов DB происходит только тогда, когда шаблон фактически использует


Я знаю, что этот вопрос старый, но я наткнулся на него, ища питонический способ получить текущий домен.

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


Я использую пользовательский тег шаблона. Добавить, например,<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 %}

{{ request.get_host }} должен защищать от атак заголовка Хоста HTTP при использовании вместе с ALLOWED_HOSTS настройка (добавлена в Django 1.4.4).

отметим, что {{ request.META.HTTP_HOST }} не имеет такой же защиты. Вижу docs:

ALLOWED_HOSTS

список строк, представляющих имена хостов / доменов, которые может обслуживать этот сайт Django. Это мера безопасности для предотвращения http Host header attacks, которые возможны даже при многих, казалось бы, безопасных конфигурациях веб-серверов.

... Если (или X-Forwarded-Host если USE_X_FORWARDED_HOST включено) не соответствует ни одному значению в этом списке,django.http.HttpRequest.get_host() метод поднять SuspiciousOperation.

... Эта проверка применяется только через get_host(); если ваш код обращается к заголовку Хоста непосредственно из request.META вы обходите эту защиту безопасности.


как использовать 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)

вот пример добавления полного URL-адреса в шаблон электронной почты;запрос.схема должен получить http или https в зависимости от того, что вы используете:

Thanks for registering! Here's your activation link:
{{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}

подобно ответу пользователя panchicore, это то, что я сделал на очень простом веб-сайте. Он предоставляет несколько переменных и делает их доступными в шаблоне.

SITE_URL будет содержать значение типа example.com
SITE_PROTOCOL будет содержать значение типа http или https
SITE_PROTOCOL_URL будет содержать значение типа http://example.com или https://example.com
SITE_PROTOCOL_RELATIVE_URL будет содержать значение как //example.com.

module/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 }}


from django.contrib.sites.models import Site
if Site._meta.installed:
    site = Site.objects.get_current()
else:
    site = RequestSite(request)

Как насчет такого подхода? Работать на меня. Он также используется в django-Регистрация.

def get_request_root_url(self):
    scheme = 'https' if self.request.is_secure() else 'http'
    site = get_current_site(self.request)
    return '%s://%s' % (scheme, site)

можно использовать {{ protocol }}://{{ domain }} в шаблонах, чтобы получить доменное имя.