it-swarm.com.ru

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

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

130
mog

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

56
phsiao

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

from Django.contrib.sites.models import Site

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

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

88
Carl Meyer

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

66
danbruegge

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

module.context_processors.py

from Django.conf import settings

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

local 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 в контекстном процессоре.

53
panchicore

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

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 гарантирует, что вызов БД происходит только тогда, когда шаблон фактически использует объект site. Это удаляет запрос со страниц администратора. Это также кеширует результат.

и включите его в настройках:

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

В шаблоне вы можете использовать {{ site.domain }} для получения текущего имени домена.

edit: для поддержки переключения протокола тоже используйте:

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)),
    }
21
vdboor

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

def myview(request):
    domain = request.build_absolute_uri('/')[:-1]
    # that will build the complete domain: http://foobar.com
16
misterte

Быстро и просто, но не подходит для производства:

(в представлении)

    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 , что имеет место, если вы используете render

Не верьте request.META['HTTP_Host'] в производство: эта информация поступает из браузера. Вместо этого используйте ответ @ CarlMeyer

12
Edward Newell

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

Обратите внимание, что {{ request.META.HTTP_Host }} не имеет такой же защиты. Смотрите документы :

Allowed_hosts

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

... Если заголовок Host (или 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 является наиболее распространенным случаем, когда вы хотите указать значение Host:

from Django.template.loader import render_to_string

def my_view(request):
    ...
    email_body = render_to_string(
        'my_template.txt', context, request=request)

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

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

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

Как и в ответе пользователя 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 }}

2
Julián Landerreche

В шаблоне Django вы можете сделать:

<a href="{{ request.scheme }}://{{ request.META.HTTP_Host }}{{ request.path }}?{{ request.GET.urlencode }}" >link</a>
0
Dos
from Django.contrib.sites.models import Site
if Site._meta.installed:
    site = Site.objects.get_current()
else:
    site = RequestSite(request)
0
Muneeb Ahmad

Как насчет этого подхода? У меня работает . Также используется в 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)
0
user9434062