Django: подача мультимедиа за пользовательский URL - PullRequest
19 голосов
/ 22 апреля 2010

Так что я, конечно, знаю, что отправка статических файлов через 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

РЕДАКТИРОВАТЬ 2 - ДОПОЛНИТЕЛЬНАЯ ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

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

Ответы [ 3 ]

18 голосов
/ 22 апреля 2010

Чтобы расширить предыдущие ответы, вы сможете изменить следующий код и сделать так, чтобы 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.filename
        response['Content-Disposition'] = 'attachment;filename=' + song.filename
    except Exception:
        raise Http404
    return response

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

3 голосов
/ 22 апреля 2010

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

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

1 голос
/ 22 апреля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...