2010-02-18 11 views
8

Come faccio a reindirizzare tutte le richieste per domain.com/... a www .domain.com/... con un 301 in un sito django?Come reindirizzare domain.com a WWW.domain.com sotto Django?

Ovviamente questo non può essere eseguito in urls.py perché in esso è presente solo la parte del percorso dell'URL.

Non riesco a utilizzare la riscrittura mod in .htaccess, perché i file .htaccess non fanno nulla sotto Django (credo).

Sto indovinando qualcosa nel middleware o nell'apache conf?

sono in esecuzione Django su un server Linux con Plesk, usando WSGI mod

+0

Cosa ti fa pensare. htaccess non funziona con Django? –

+0

L'ho provato. Ma la riscrittura mod non è il mio punto di forza, quindi è probabile che abbia sbagliato. – Jake

risposta

18

Il WebFaction discussione qualcuno ha sottolineato è corretto per quanto riguarda la configurazione, devi solo applicarlo tu stesso piuttosto che attraverso un pannello di controllo.

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

Inserire nel file .htaccess o nella configurazione principale di Apache nel contesto appropriato. Se all'interno di un VirtualHost nella configurazione principale di Apache, si dovrebbe avere ServerName essere www.example.com e ServerAlias ​​essere example.com per garantire che l'host virtuale gestisca entrambe le richieste.

Se non si ha accesso a nessuna configurazione di Apache, se necessario, è possibile farlo utilizzando un wrapper WSGI attorno al punto di ingresso dell'applicazione Django WSGI. Qualcosa di simile:

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) 

Fissaggio questo fino a includere l'URL all'interno del sito e trattare con https è lasciata come esercizio per il lettore. :-)

+0

Questo è un piccolo snippet WSGI piuttosto carino. Decisamente più elegante della cosa che ho collegato. – jathanism

+1

Ho barato un po 'però. Ho assunto solo "http" e non mi sono preso la briga di ricostruire l'intero URL e lo ho lasciato al lettore. Volevo mostrare il concetto più di ogni altra cosa. Il middleware Django è più corretto. Nel complesso però, mod_rewrite dovrebbe semplicemente essere usato. –

+1

La configurazione di Apache/Lighttpd/nginx è più efficiente dell'uso di django per questo lavoro. – jujule

0

Un filo completo circa il problema esiste qui http://forum.webfaction.com/viewtopic.php?id=1516

+0

Quella discussione si riferisce a un pannello di controllo che non ho. Fornisce un collegamento ai documenti Django per PREPEND_WWW, questo è il comportamento di cui ho bisogno, ma preferirei un reindirizzamento 301. – Jake

+0

Le sole risposte di collegamento non sono grandi perché non contengono la risposta e il collegamento potrebbe diventare obsoleto. – Flimm

15

L'impostazione PREPEND_WWW fa proprio questo.

+4

Questo è utile, ma vale la pena notare che è completamente indiscriminato ... aggiungerà sempre un www se non ce n'è uno, quindi per un sito accessibile anche da sottodomini che non dovrebbero iniziare con www, qualcosa come i suggerimenti di Graham diventa necessario. – kungphu

0

Anche questo può essere fatto con un middleware.

Alcuni esempi:

Questa è una versione migliore di frammento-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

C'è a better way to do that. Si dovrebbe solo aggiungere nella configurazione di Apache al tuo default VirtualHost un altro, che sarà definita come:

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

E che farà il lavoro.

0

Ho provato la soluzione di Graham ma non riesco a farla funzionare (anche se il caso più semplice di http (non https) senza alcun percorso. Non ho esperienza con wsgi come puoi probabilmente supporre e tutto l'aiuto è profondamente apprezzato

Ecco il mio tentativo (reindirizzamento da www.olddomain.com a www.newdomain.com).Quando provo a distribuirlo, cercando di raggiungere www.olddomain.com risultati in un errore ("Impossibile raggiungere la pagina"):

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) 

Grazie per il vostro aiuto

Problemi correlati