2010-04-22 19 views
15

Więc oczywiście wiem, że przesyłanie statycznych plików przez Django wyśle ​​cię prosto do piekła, ale jestem zdezorientowany, jak użyć niestandardowego adresu URL, aby zamaskować prawdziwą lokalizację pliku przy użyciu Django. Django: Serving a Download in a Generic View, ale odpowiedź, którą zaakceptowałem, wydaje się być "niewłaściwym" sposobem robienia rzeczy.Django: Serwowanie multimediów za niestandardowym adresem 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 

To rozwiązanie działa doskonale ale nie na tyle doskonale się okazuje. Jak mogę uniknąć bezpośredniego linku do pliku mp3 przy jednoczesnym wyświetlaniu przez nginx/apache?

EDIT 1 - DODATKOWE INFORMACJE

Obecnie mogę dostać moje pliki za pomocą adresu takich jak: http://www.example.com/music/song/1692/download/ Ale wyżej metoda jest dzieło diabła.

W jaki sposób mogę osiągnąć to, co dostaję powyżej, a jednocześnie sprawia, że ​​nginx/apache obsługuje media? Czy jest to coś, co należy zrobić na poziomie serwera WWW? Jakiś szalony mod_rewrite?

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

EDIT 2 - DODATKOWE INFORMACJE DODATKOWE

Używam nginx dla mojego frontend i reverse proxy z powrotem serwer apache/rozwojowy więc myślę, że jeśli to wymaga jakiegoś mod_rewrite pracy będę miał znaleźć coś, co zadziała z nginxem.

Odpowiedz

15

Aby rozwinąć poprzednie odpowiedzi, powinieneś być w stanie zmodyfikować poniższy kod i mieć Nginx bezpośrednio udostępniać pliki do pobrania, jednocześnie chroniąc pliki.

Przede wszystkim dodać lokalizację takich jak:

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

do pliku nginx.conf (wewnętrzna sprawia, że ​​ten nie jest dostępny bezpośrednio). Następnie potrzebujesz Django View coś podobnego:

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 

, który przekaże plik do pobrania do nginx.

+0

To jest dokładnie to, czego potrzebowałem, dzięki! – TheLizardKing

+0

Dziękuję wam obojgu. Szukałem od jakiegoś czasu dla tego rozwiązania i dostałem dużo hałasu! – Sebastien

1

Zarówno httpd, jak i Nginx mają sposób określenia statycznego pliku do wyświetlenia za pośrednictwem nagłówka. Dokładny nagłówek jest jednak różny, więc najlepiej jest umieścić coś w ustawieniach, aby wybrać metodę.

3

Podstawową ideą jest przekonwertowanie widoku Django na bezpieczny adres URL obsługiwany przez serwer multimediów.

Zobacz this list sugestii Grahama Dumpletona, autora mod_wsgi.

Powiązane problemy