Django es el entorno de desarrollo web para perfeccionistas con límites de tiempo

Subdominios con Django

En ocasiones nos interesa trabajar con subdominios en nuestros proyectos Django. Para ello podemos utilizar un sencillo middleware para subdominios que podemos encontrar en djangosnippets. Basta con guardarlo en nuestro proyecto e incluirlo en la lista MIDDLEWARE_CLASSES de nuestro settings.py. De esta forma tendremos el subdominio de la petición en la variable subdomain del objeto request.

El problema al trabajar con subdominios es que las sesiones iniciadas en un subdominio no se mantienen cuando se cambia a otro. Para poder mantener activas las sesiones entre subdominios tenemos que añadir la siguiente línea al settings.py de nuestro proyecto:

SESSION_COOKIE_DOMAIN = '.mi-dominio.com'

De esta forma la cookie de sesión que se almacena en el navegador valdrá para todos los subdominios.

Subdominios para usuarios

Si por ejemplo queremos dar un subdominio a cada usuario de nuestro proyecto podemos modificar el middleware para que busque el usuario adecuado y lo incluya en el objeto request. El middleware quedaría de la siguiente manera:

from django.http import Http404
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.models import User

class SubdomainMiddleware:
    """ Make the subdomain publicly available to classes """

    def process_request(self, request):
        domain_parts = request.get_host().split('.')
        if (len(domain_parts) > 2):
            subdomain = domain_parts[0]
            if (subdomain.lower() == 'www'):
                subdomain = ''
            domain = '.'.join(domain_parts[1:])
        else:
            subdomain = ''
            domain = request.META['HTTP_HOST']

        request.subdomain = subdomain
        request.domain = domain

        if subdomain != 'www' and subdomain != '':
            # Buscamos el usuario del subdominio
            try:
                request.usuario_subdominio = User.objects.filter(username=subdomain)
            except ObjectDoesNotExist:
                raise Http404

De esta forma el usuario correspondiente al subdominio que se visita está disponible en la variable usuario_subdominio del objeto request. Si utilizamos variables de contexto y tenemos 'django.core.context_processors.request' en la lista de procesadores de contexto (setting TEMPLATE_CONTEXT_PROCESSORS) podemos obtener el usuario actual en nuestras plantillas mediante:

{{ request.usuario_subdominio }}

Publicado por Antonio Melé el Domingo 2 d Agosto d 2009 Compártelo: Facebook: Twitter: | Categorías: middleware, snippets, trucos, urls

Entradas similares

Templatetag {% if %} con más comparaciones

Este snippet reemplaza la funcionalidad del templatetag {% if %} permitiendo realizar comparaciones con operadores >, <, >=, <=, != además de las comparaciones que permite hacer {% if %} por defecto. Por ...


Middleware para detectar visitas desde buscadores

Saber si nuestro visitante viene de un buscador es interesante en varios casos. Por ejemplo para almacenar el término de búsqueda que le ha ...


 
Templatetags globales en nuestros proyectos Django

Los templatetags de Django son a nivel de aplicación. Sin embargo a veces nos gustaría que distintas aplicaciones compartieran templatetags ó evitarnos tener que ...


Trabajar con slugs en URLs

Una de las cosas que los buscadores tienen en cuenta para establecer la relevancia de sus resultados son las palabras que aparecen en las ...


 
 

6 comentarios:

El Domingo 2 de Agosto de 2009 Arkanus dijo:

Pero no es necesario usar vistas genéricas o añadir un RequestContext para usar las variables desde los templates?

El Domingo 2 de Agosto de 2009 Antonio Melé dijo:

Arkanus, gracias por comentarlo. A eso me refiero con utilizar variables de contexto pero para dejarlo más claro un ejemplo de utilización de variables de contexto sería:

from django.template import RequestContext
from django.shortcuts import render_to_response

def mi_vista(request):
# ...
return render_to_response('pagina.html', context_instance=RequestContext(request))

El Sábado 1 de Agosto de 2009 Arkanus dijo:

Ok, pensé que había una forma automágica de incluir el RequestContext que no conocía.
Gracias por la aclaración

El Viernes 7 de Agosto de 2009 Christopher dijo:

Tambien:

Usar
request.urlconf = 'project.app.urls'

en Middleware para urls solo esto subdominio

El Jueves 23 de Septiembre de 2010 Reiner Marquez dijo:
este ejemplo tiene com oinconveniente que no funciona el dominios que no tengan 2 niveles, por ejemplo, digase: localhost (1 nivel) .subuno.uno.com (3 niveles) algo que pudiese resolver esto pudiera ser obtener el subdominio a partir del current_site, y asi quedaria mas generico. de hecho ya el current_site contendria el dominio. site = Site.objects.get_current() pattern = r'^(?:(?P.*?)\.)?%s(?::.*)?$' % re.escape(site.domain) matches = re.match(pattern, request.get_host()) if matches: request.subdomain = matches.group('subdomain') else: request.subdomain = None con el animo de contribuir con este valioso sitio pd: basado en el pluggable django-subdomain
El Miércoles 22 de Septiembre de 2010 Reiner Marquez dijo:

este ejemplo tiene como inconveniente que no funciona el dominios que no tengan 2 niveles, por ejemplo,

  • subdominio.localhost (1 nivel)
  • subdominio.subuno.uno.com (3 niveles)

algo que pudiese resolver esto pudiera ser obtener el subdominio a partir del current_site, y asi quedaria mas generico. de hecho ya el current_site contendria el dominio.

site = Site.objects.get_current()
pattern = r'^(?:(?P.*?)\.)?%s(?::.*)?$' % re.escape(site.domain)
matches = re.match(pattern, request.get_host())

if matches:
  request.subdomain = matches.group('subdomain')
else:
  request.subdomain = None

con el animo de contribuir con este valioso sitio
pd: basado en el pluggable django-subdomain

Escribe un comentario:

captcha