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?
РЕДАКТИРОВАТЬ 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
РЕДАКТИРОВАТЬ 2 - ДОПОЛНИТЕЛЬНАЯ ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ
Я использую nginx для моего интерфейса и обратного прокси-сервера back apache/development, поэтому я думаю, что если он требует какой-то работы mod_rewrite, мне нужно будет найти что-то, что будет работать с nginx.
Ответы
Ответ 1
Чтобы развернуть предыдущие ответы, вы должны иметь возможность изменить следующий код и иметь nginx, напрямую обслуживающий ваши файлы для скачивания, в то же время сохраняя защищенные файлы.
Прежде всего добавьте местоположение, например:
location /files/ {
alias /true/path/to/mp3/files/;
internal;
}
к вашему файлу nginx.conf(внутреннее делает это напрямую недоступным). Затем вам понадобится Django. Посмотрите что-то вроде этого:
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
который передаст загрузку файла в nginx.
Ответ 2
Основная идея заключается в том, чтобы ваше представление Django перенаправлялось на защищенный URL-адрес, обслуживаемый вашим медиа-сервером.
См. этот список предложений Грэма Дамплтона, автора mod_wsgi.
Ответ 3
Оба httpd и Nginx имеют способ указать статический файл для обслуживания через заголовок. Точный заголовок меняется, поэтому лучше всего поместить что-то в настройки, чтобы выбрать метод.