2010-04-22 8 views
15

So weiß ich natürlich, dass Serving statische Dateien durch Django Sie direkt in die Hölle schicken, aber ich bin verwirrt darüber, wie eine benutzerdefinierte URL verwenden, um den wahren Speicherort der Datei mit Django zu maskieren. Django: Serving a Download in a Generic View aber die Antwort, die ich akzeptiert scheint die „falsche“ Art und Weise, Dinge zu tun zu sein.Django: Serving Media Hinter Benutzerdefinierte URL

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 

Diese Lösung perfekt aber nicht perfekt genug funktioniert es stellt sich heraus. Wie kann ich vermeiden, eine direkte Verbindung zum mp3 zu haben, während ich noch über nginx/apache diene?

EDIT 1 - ZUSÄTZLICHE INFORMATIONEN

Zur Zeit kann ich meine Dateien erhalten, indem eine Adresse verwenden wie: http://www.example.com/music/song/1692/download/ Aber die oben genannten Verfahren ist das Werk des Teufels.

Wie kann ich erreicht, was ich oben erhalten, während machen noch nginx/Apache die Medien dienen? Soll das auf Webserverebene geschehen? Einige verrückte mod_rewrite?

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

EDIT 2 - ZUSATZ ZUSÄTZLICHE INFORMATIONEN

ich nginx für mein Frontend verwenden und Reverse-Proxy zurück Apache/Entwicklungs-Server so dass ich denke, wenn es irgendeine Art von mod_rewrite Arbeit benötigt werde ich um etwas zu finden, das mit nginx funktionieren würde.

Antwort

15

Um die vorherigen Antworten zu erweitern, sollten Sie in der Lage sein, den folgenden Code zu ändern und nginx direkt Ihre Download-Dateien zu bedienen, während die Dateien weiterhin geschützt sind.

Zu allererst fügen Sie einen Ort wie:

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

auf Ihre nginx.conf Datei (die interne macht dies nicht direkt zugänglich). Dann benötigen Sie eine Django-Ansicht etwa wie folgt:

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 

die Übergabe der Datei an nginx übergeben wird.

+0

Das ist ziemlich genau das, was ich brauchte, danke! – TheLizardKing

+0

Dank der beiden von Ihnen. Ich habe eine Weile nach dieser Lösung gesucht und viel Lärm bekommen! – Sebastien

1

Sowohl httpd als auch Nginx haben eine Möglichkeit, eine statische Datei anzugeben, die über einen Header bereitgestellt wird. Die genaue Kopfzeile variiert jedoch. Daher empfiehlt es sich, etwas in die Einstellungen einzufügen, um die Methode auszuwählen.

3

Die Grundidee ist Ihre Django-Ansicht gelangen auf eine sichere URL zu umleiten, die von Ihrem Media-Server bedient wird.

Siehe this list Vorschläge von Graham Dumpleton, Autor von mod_wsgi.