Django: обслуживание медиафайлов за пользовательским URL-адресом

Поэтому я, конечно, знаю, что обслуживание статических файлов через Django отправит вас прямо в ад, но я смущен тем, как использовать настраиваемый url для маскировки истинного местоположения файла с помощью Django. Django: обслуживание загрузки в общем представлении, но ответ, который я принял, кажется, является «неправильным» способом делать вещи.

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 

Это решение работает отлично, но не вполне достаточно. Как я могу избежать прямой ссылки на mp3, пока все еще работает через nginx / apache?

EDIT 1 – ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

В настоящее время я могу получить свои файлы, используя адрес, например: http://www.example.com/music/song/1692/download/ Но вышеупомянутый метод – это работа дьявола.

Как я могу выполнить то, что я получаю выше, но при этом nginx / apache обслуживает медиа? Это что-то должно быть сделано на уровне веб-сервера? Какой-то сумасшедший mod_rewrite?

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

EDIT 2 – ДОПОЛНИТЕЛЬНАЯ ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

Я использую nginx для моего интерфейса и обратного прокси-сервера back apache / development, поэтому я думаю, что если он потребует какой-то работы mod_rewrite, мне придется найти что-то, что будет работать с nginx.

Чтобы развернуть предыдущие ответы, вы должны иметь возможность изменить следующий код и иметь nginx, который напрямую обслуживает ваши файлы для скачивания, в то же время сохраняя защищенные файлы.

Прежде всего добавьте местоположение, такое как:

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

к вашему файлу nginx.conf (внутреннее делает это напрямую недоступным). Тогда вам понадобится Django View:

 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.filenamename response['Content-Disposition'] = 'attachment;filename=' + song.filename except Exception: raise Http404 return response 

который передаст загрузку файла в nginx.

Основная идея заключается в том, чтобы ваше Django-представление перенаправлялось на защищенный URL-адрес, обслуживаемый вашим медиа-сервером.

См. Этот список предложений Грэма Дамплтона, автора mod_wsgi.

И httpd, и Nginx имеют способ указать статический файл для обслуживания через заголовок. Точный заголовок меняется, поэтому, чтобы лучше выбрать что-то в настройках, выберите метод.