2010-02-18 10 views
8

¿Cómo hago para redirigir todas las solicitudes de domain.com/... a www .domain.com/... con un 301 en un sitio django?¿Cómo redirecciono domain.com a WWW.domain.com en Django?

Obviamente, esto no se puede hacer en urls.py porque solo se obtiene la parte de la ruta de la URL allí.

No puedo usar la modificación de mods en .htaccess, porque los archivos .htaccess no hacen nada en Django (creo).

Supongo que algo en middleware o apache conf?

estoy corriendo Django en un servidor Linux con Plesk, utilizando WSGI mod

+0

Qué le hace pensar. htaccess no funciona con Django? –

+0

Lo probé. Pero la reescritura mod no es mi punto fuerte, por lo que es probable que haya estado mal. – Jake

Respuesta

18

La discusión WebFaction alguien señaló es correcta en cuanto a la configuración, solo tiene que aplicarlo usted mismo en lugar de a través de un panel de control.

RewriteEngine On 
RewriteCond %{HTTP_HOST} ^example.com$ 
RewriteRule (.*) http://www.example.com/$1 [R=301,L] 

Coloque el archivo .htaccess, o en la configuración principal de Apache en el contexto apropiado. Si está dentro de un VirtualHost en la configuración principal de Apache, tendría ServerName ser www.example.com y ServerAlias ​​ser example.com para asegurarse de que el host virtual maneja ambas solicitudes.

Si no tiene acceso a ninguna configuración de Apache, si es necesario, puede hacerlo utilizando un contenedor WSGI alrededor del punto de entrada de la aplicación Django WSGI. Algo así como:

import django.core.handlers.wsgi 
_application = django.core.handlers.wsgi.WSGIHandler() 

def application(environ, start_response): 
    if environ['HTTP_HOST'] != 'www.example.com': 
    start_response('301 Redirect', [('Location', 'http://www.example.com/'),]) 
    return [] 
    return _application(environ, start_response) 

La fijación de este para incluir la URL dentro del sitio y tratar con https se deja como ejercicio para el lector. :-)

+0

Ese es un pequeño y bonito fragmento de WSGI. Definitivamente más elegante que lo que conecté. – jathanism

+1

Aunque he engañado un poco. He asumido 'http' solamente y no me he molestado en reconstruir la URL completa y la dejé en manos del lector. Quería mostrar el concepto más que nada. El middleware de Django es más correcto. Sin embargo, en general, mod_rewrite simplemente debería ser utilizado. –

+1

Usar la configuración de Apache/Lighttpd/nginx es más eficiente que usar django para este trabajo. – jujule

0

Existe una rosca completa sobre el tema aquí http://forum.webfaction.com/viewtopic.php?id=1516

+0

Ese hilo se refiere a un panel de control que no tengo. Da un enlace a los documentos de Django para PREPEND_WWW, este es el comportamiento que necesito, pero prefiero un redireccionamiento 301. – Jake

+0

Las respuestas de enlace único no son excelentes porque no contienen la respuesta y el enlace puede volverse obsoleto. – Flimm

15

La configuración PREPEND_WWW hace precisamente eso.

+4

Esto es útil, pero vale la pena señalar que es completamente indiscriminado ... siempre agregará un www si no hay uno, por lo que para un sitio al que también se puede acceder desde subdominios que no deberían comenzar con www, algo así como las sugerencias de Graham se vuelve necesario – kungphu

0

Esto también se puede hacer con un middleware.

Algunos ejemplos:

Esta es una versión mejorada de fragmento-510:

class UrlRedirectMiddleware(object): 
    """ 
    This middleware lets you match a specific url and redirect the request to a 
    new url. You keep a tuple of (regex pattern, redirect) tuples on your site 
    settings, example: 

    URL_REDIRECTS = (
     (r'(https?)://(www\.)?sample\.com/(.*)$', r'\1://example.com/\3'), 
    ) 
    """ 
    def process_request(self, request): 
     full_url = request.build_absolute_uri() 
     for url_pattern, redirect in settings.URL_REDIRECTS: 
      match = re.match(url_pattern, full_url) 
      if match: 
       return HttpResponsePermanentRedirect(match.expand(redirect)) 
3

Hay a better way to do that. Usted sólo debe añadir en la configuración de Apache para su default VirtualHost otro, que se define como:

<VirtualHost *:80> 
    ServerName domain.com 
    Redirect permanent/http://www.domain.com/ 
</VirtualHost> 

y que va a hacer el trabajo.

0

He intentado la solución de Graham pero no puedo hacer que funcione (incluso si el caso más simple de http (no https) sin ningún camino. No tengo experiencia con wsgi como probablemente pueda adivinar y toda la ayuda es muy apreciado.

Aquí está mi intento (redirigiendo desde www.olddomain.com a www.newdomain.com).Cuando trato de desplegarlo, tratando de llegar a www.olddomain.com resulta en un error ("No se puede llegar a esta página"):

from django.core.wsgi import get_wsgi_application 

_application = get_wsgi_application() 

def application(environ, start_response): 
    if environ['HTTP_HOST'][:21] == 'www.olddomain.com': 
    start_response('301 Redirect', [('Location', 'http://www.newdomain.com/'),]) 
    return [] 

    return _application(environ, start_response) 

Gracias por su ayuda

Cuestiones relacionadas