¿Cómo puedo obtener el nombre de dominio de mi sitio dentro de una plantilla de Django?


¿Cómo obtengo el nombre de dominio de mi sitio actual desde una plantilla de Django? He intentado buscar en la etiqueta y los filtros, pero nada allí.

Author: phsiao, 2009-09-20

13 answers

Creo que lo que desea es tener acceso al contexto de la solicitud, consulte RequestContext.

 53
Author: phsiao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-20 14:35:03

Si desea el encabezado del host HTTP real, consulte el comentario de Daniel Roseman en la respuesta de @Phsiao. La otra alternativa es si estás usando el contrib .sites framework , puede establecer un nombre de dominio canónico para un Sitio en la base de datos (asignar el dominio de solicitud a un archivo de configuración con el SITE_ID adecuado es algo que tiene que hacer usted mismo a través de la configuración de su servidor web). En ese caso usted está buscando:

from django.contrib.sites.models import Site

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

Tendría que poner el objeto current_site en un contexto de plantilla a ti mismo si quieres usarlo. Si lo estás usando por todas partes, podrías empaquetarlo en un procesador de contexto de plantilla.

 84
Author: Carl Meyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-06 22:34:02

He descubierto la {{ request.get_host }} método.

 60
Author: danbruegge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-06 16:55:52

Complementando a Carl Meyer, puedes hacer un procesador de contexto como este:

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",
    ....
 )

Plantillas que devuelven la instancia de contexto el sitio url es {{ SITE_URL }}

Puede escribir su propia rutina si desea manejar subdominios o SSL en el procesador de contexto.

 53
Author: panchicore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-13 15:59:31

La variación del procesador de contexto que uso es:

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

El wrapper SimpleLazyObject se asegura de que la llamada a DB solo ocurra cuando la plantilla realmente usa el objeto site. Esto elimina la consulta de las páginas de administración. También almacena en caché el resultado.

E incluirlo en la configuración:

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

En la plantilla, puede usar {{ site.domain }} para obtener el nombre de dominio actual.

Editar: para soportar el cambio de protocolo también, use:

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)),
    }
 20
Author: vdboor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-19 08:22:40

Sé que esta pregunta es antigua, pero me topé con ella buscando una forma pitónica de obtener el dominio actual.

def myview(request):
    domain = request.build_absolute_uri('/')[:-1]
    # that will build the complete domain: http://foobar.com
 14
Author: misterte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-28 02:54:02

Rápido y simple, pero no bueno para la producción:

(en una vista)

    request.scheme               # http or https
    request.META['HTTP_HOST']    # example.com
    request.path                 # /some/content/1/

(en una plantilla)

{{ request.scheme }} :// {{ request.META.HTTP_HOST }} {{ request.path }}

Asegúrese de usar un RequestContext, que es el caso si está utilizando render.

No confíes en request.META['HTTP_HOST'] en la producción: esa información proviene del navegador. En su lugar, utilice la respuesta de @ CarlMeyer

 11
Author: Edward Newell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-07 07:34:59

Uso una etiqueta de plantilla personalizada. Añadir, por ejemplo, <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

Usarlo en una plantilla como esta:

{% load site %}
{% current_domain %}
 8
Author: Dennis Golomazov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-10 11:48:12

{{ request.get_host }} debe protegerse contra ataques de encabezado de host HTTP cuando se usa junto con la configuración ALLOWED_HOSTS (añadida en Django 1.4.4).

Tenga en cuenta que {{ request.META.HTTP_HOST }} no tiene la misma protección. Véase el docs :

ALLOWED_HOSTS

Una lista de cadenas que representan los nombres de host/dominio que este sitio Django puede servir. Esta es una medida de seguridad para prevenir ataques de encabezado de host HTTP, que son posibles incluso bajo muchos servidores web aparentemente seguros configuraciones.

... Si el encabezado Host (o X-Forwarded-Host si USE_X_FORWARDED_HOST está habilitado) no coincide con ningún valor de esta lista, el método django.http.HttpRequest.get_host() elevará SuspiciousOperation.

... Esta validación solo se aplica a través de get_host(); si su código accede al encabezado del host directamente desde request.META, está eludiendo esta protección de seguridad.


En cuanto al uso de request en su plantilla, las llamadas a la función de representación de plantillas han cambiado en Django 1.8 , por lo que ya no tiene para manejar RequestContext directamente.

A continuación se muestra cómo renderizar una plantilla para una vista, utilizando la función de acceso directo render():

from django.shortcuts import render

def my_view(request):
    ...
    return render(request, 'my_template.html', context)

Aquí le mostramos cómo renderizar una plantilla para un correo electrónico, que IMO es el caso más común en el que desea el valor de host:

from django.template.loader import render_to_string

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

Aquí hay un ejemplo de agregar una URL completa en una plantilla de correo electrónico; solicitud.scheme debe obtener http o https dependiendo de lo que esté usando:

Thanks for registering! Here's your activation link:
{{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
 8
Author: S. Kirby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-04 01:50:26

Similar a la respuesta del usuario panchicore, esto es lo que hice en un sitio web muy simple. Proporciona algunas variables y las hace disponibles en la plantilla.

SITE_URL se mantenga un valor como example.com
SITE_PROTOCOL se mantenga un valor como http o https
SITE_PROTOCOL_URL se mantenga un valor como http://example.com o https://example.com
SITE_PROTOCOL_RELATIVE_URL se mantenga un valor como //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'

Luego, en sus plantillas, use como {{ SITE_URL }}, {{ SITE_PROTOCOL }}, {{ SITE_PROTOCOL_URL }} y {{ SITE_PROTOCOL_RELATIVE_URL }}

 2
Author: Julián Landerreche,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-22 19:25:39
from django.contrib.sites.models import Site
if Site._meta.installed:
    site = Site.objects.get_current()
else:
    site = RequestSite(request)
 0
Author: Muneeb Ahmad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-08 22:53:26

¿Qué pasa con este enfoque? Funciona para mí. También se usa en django-registration .

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
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-04 12:17:05

Puede usar {{ protocol }}://{{ domain }} en sus plantillas para obtener su nombre de dominio.

 -3
Author: Erwan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-20 15:15:21