introduccion - https tutorial djangogirls org es
¿Cómo puedo obtener el nombre de dominio de mi sitio dentro de una plantilla de Django? (13)
¿Cómo obtengo el nombre de dominio de mi sitio actual desde una plantilla de Django? Intenté buscar en la etiqueta y los filtros, pero no encontré nada.
¿Qué hay de este enfoque? Funciona para mi. 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)
Al igual que la respuesta del usuario panchicore, esto es lo que hice en un sitio web muy simple. Proporciona algunas variables y las pone a disposición en la plantilla.
SITE_URL
tendría un valor como example.com
SITE_PROTOCOL
contendría un valor como http
o https
SITE_PROTOCOL_URL
tendría un valor como http://example.com
o https://example.com
SITE_PROTOCOL_RELATIVE_URL
tendría 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, utilícelas como {{ SITE_URL }}
, {{ SITE_PROTOCOL }}
, {{ SITE_PROTOCOL_URL }}
y {{ SITE_PROTOCOL_RELATIVE_URL }}
Complementando a Carl Meyer, puedes crear 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 instancia de contexto, el sitio url es {{SITE_URL}}
puede escribir su propia rutina si quiere manejar subdominios o SSL en el procesador de contexto.
Creo que lo que desea es tener acceso al contexto de solicitud, vea RequestContext.
Descubrí el método {{ request.get_host }}
.
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 contenedor SimpleLazyObject
se asegura de que la llamada al DB solo suceda cuando la plantilla realmente usa el objeto del site
. Esto elimina la consulta de las páginas de administración. También almacena el resultado en caché.
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 admitir 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)),
}
Puede usar {{ protocol }}://{{ domain }}
en sus plantillas para obtener su nombre de dominio.
Rápido y simple, pero no es 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á usando render .
No confíe en request.META[''HTTP_HOST'']
en producción: esa información proviene del navegador. En cambio, usa la respuesta de @ CarlMeyer
Sé que esta pregunta es antigua, pero me encontré con ella en busca de una forma pitónica para obtener el dominio actual.
def myview(request):
domain = request.build_absolute_uri(''/'')[:-1]
# that will build the complete domain: http://foobar.com
Si desea el encabezado HTTP Host real, consulte el comentario de Daniel Roseman sobre la respuesta de @ Phsiao. La otra alternativa es que si usa el marco contrib.sites , puede establecer un nombre de dominio canónico para un Sitio en la base de datos (mapear 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 su configuración del servidor web). En ese caso lo que estás 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 si quiere usarlo. Si lo está usando por todas partes, puede empaquetarlo en un procesador de contexto de plantilla.
Yo uso una etiqueta de plantilla personalizada. Agregar a, 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
Úselo en una plantilla como esta:
{% load site %}
{% current_domain %}
{{ request.get_host }}
debería proteger contra ataques de encabezado HTTP Host cuando se usa junto con la configuración ALLOWED_HOSTS
(agregada en Django 1.4.4).
Tenga en cuenta que {{ request.META.HTTP_HOST }}
no tiene la misma protección. Ver los docs :
ALLOWED_HOSTS
Una lista de cadenas que representan los nombres de host / dominio que puede servir este sitio de Django. Esta es una medida de seguridad para evitar los ataques de encabezado HTTP Host , que son posibles incluso bajo muchas configuraciones de servidor web aparentemente seguras.
... Si el encabezado
Host
(oX-Forwarded-Host
siUSE_X_FORWARDED_HOST
está habilitado) no coincide con ningún valor en esta lista, el métododjango.http.HttpRequest.get_host()
levantaráSuspiciousOperation
.... Esta validación solo se aplica a través de
get_host()
; si su código accede al encabezado del host directamente desderequest.META
, está pasando por alto esta protección de seguridad.
En cuanto a utilizar la request
en su plantilla, las llamadas a la función de representación de plantilla han cambiado en Django 1.8 , por lo que ya no tendrá que manejar RequestContext
directamente.
A continuación, se explica cómo representar una plantilla para una vista mediante la función de acceso directo render()
:
from django.shortcuts import render
def my_view(request):
...
return render(request, ''my_template.html'', context)
A continuación, se indica cómo presentar una plantilla para un correo electrónico, que IMO es el caso más común en el que desearía 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 cómo agregar una URL completa en una plantilla de correo electrónico; request.scheme debería obtener http
o https
dependiendo de lo que estés usando:
Thanks for registering! Here''s your activation link:
{{ request.scheme }}://{{ request.get_host }}{% url ''registration_activate'' activation_key %}
from django.contrib.sites.models import Site
if Site._meta.installed:
site = Site.objects.get_current()
else:
site = RequestSite(request)