2010-04-22 15 views
15

Quindi ovviamente so che servire file statici tramite Django ti manderà dritta al diavolo ma sono confuso su come usare un URL personalizzato per mascherare la vera posizione del file usando Django. Django: Serving a Download in a Generic View ma la risposta che ho accettato sembra essere il modo "sbagliato" di fare le cose.Django: Supporti multimediali dietro l'URL personalizzato

urls.py:

url(r'^song/(?P<song_id>\d+)/download/$', song_download, name='song_download'), 

views.py:

def song_download(request, song_id): 
    song = Song.objects.get(id=song_id) 
    fsock = open(os.path.join(song.path, song.filename)) 

    response = HttpResponse(fsock, mimetype='audio/mpeg') 
    response['Content-Disposition'] = "attachment; filename=%s - %s.mp3" % (song.artist, song.title) 

    return response 

Questa soluzione funziona perfettamente ma non abbastanza perfettamente si scopre. Come posso evitare di avere un collegamento diretto con l'mp3 mentre sto ancora utilizzando nginx/apache?

EDIT 1 - INFORMAZIONI AGGIUNTIVE

Attualmente posso ottenere il mio file utilizzando un indirizzo come: http://www.example.com/music/song/1692/download/ Ma il metodo di cui sopra è opera del diavolo.

Come posso ottenere ciò che ottengo mentre sto ancora facendo nginx/apache per i media? È qualcosa che dovrebbe essere fatto a livello di webserver? Qualche mod_rewrite pazzo?

http://static.example.com/music/Aphex%20Twin%20-%20Richard%20D.%20James%20(V0)/10%20Logon-Rock%20Witch.mp3

EDIT 2 - ULTERIORI INFORMAZIONI AGGIUNTIVE

Io uso nginx per il mio frontend e invertire server Apache/sviluppo procura indietro quindi penso che se si richiede un certo tipo di lavoro mod_rewrite avrò per trovare qualcosa che possa funzionare con nginx.

risposta

15

Per espandere le risposte precedenti dovresti essere in grado di modificare il codice seguente e fare in modo che nginx serva direttamente i file di download pur avendo i file protetti.

Prima di tutto aggiungere una posizione, ad esempio:

location /files/ { 
    alias /true/path/to/mp3/files/; 
    internal; 
} 

al file nginx.conf (l'interno rende questo non è direttamente accessibile). Allora hai bisogno di un Django Vedi qualcosa del genere:

def song_download(request, song_id): 
    try: 
     song = Song.objects.get(id=song_id) 
     response = HttpResponse() 
     response['Content-Type'] = 'application/mp3' 
     response['X-Accel-Redirect'] = '/files/' + song.filename 
     response['Content-Disposition'] = 'attachment;filename=' + song.filename 
    except Exception: 
     raise Http404 
    return response 

che distribuirà il file in nginx.

+0

Questo è praticamente esattamente ciò di cui avevo bisogno, grazie! – TheLizardKing

+0

Grazie a tutti e due. Sono stato alla ricerca di un po 'di tempo per quella soluzione e ho avuto un sacco di rumore! – Sebastien

1

Entrambi httpd e Nginx hanno un modo per specificare un file statico da servire tramite un'intestazione. L'intestazione esatta varia però, quindi è meglio mettere qualcosa nelle impostazioni per scegliere il metodo.

3

L'idea di base è di reindirizzare la vista di Django a un URL sicuro offerto dal server multimediale.

Vedere this list di suggerimenti di Graham Dumpleton, autore di mod_wsgi.

Problemi correlati