Подтвердить что ты не робот

Как вернуть статические файлы, проходящие через представление в django?

Мне нужно вернуть файлы css и js файлы в соответствии с определенной логикой. Ясно, что статическая подача не выполняет то, что мне нужно. У меня есть представление, метод визуализации которого использует логику для поиска нужного файла, но тогда я должен вернуть его. Технически я могу просто прочитать файл и добавить его в объект HttpResponse с соответствующим типом mime, но мне было интересно, есть ли лучшая стратегия. (например, fpassthru() в php)

4b9b3361

Ответ 1

Это то, что я использовал:

test_file = open('/home/poop/serve/test.pdf', 'rb')
response = HttpResponse(content=test_file)
response['Content-Type'] = 'application/pdf'
response['Content-Disposition'] = 'attachment; filename="%s.pdf"' \
                                  % 'whatever'
return response

Ответ 2

Какое программное обеспечение веб-сервера вы используете?

По крайней мере, для Apache и NginX существует модуль, позволяющий использовать заголовок X-SendFile HTTP. Сайт NginX говорит, что Lighty тоже может это сделать.

В представлении оболочки:

...

abspath = '/most_secret_directory_on_the_whole_filesystem/protected_filename.css'

response = HttpResponse()
response['X-Sendfile'] = abspath

response['Content-Type'] = 'mimetype/submimetype'
# or let your webserver auto-inject such a header field
# after auto-recognition of mimetype based on filename extension

response['Content-Length'] = <filesize>
# can probably be left out if you don't want to hassle with getting it off disk.
# oh, and:
# if the file is stored via a models.FileField, you just need myfilefield.size

response['Content-Disposition'] = 'attachment; filename=%s.css' \
    % 'whatever_public_filename_you_need_it_to_be'

return response

Затем вы можете подключить представление через http://mysite.com/url_path/to/serve_hidden_css_file/.

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

Для Apache: http://tn123.ath.cx/mod_xsendfile/
Для NginX: http://wiki.nginx.org/NginxXSendfile

Ответ 3

Почему бы вам не использовать статические файлы Django внутри вашего представления

from django.contrib.staticfiles.views import serve

...
def view_function(request):
   return serve(request, 'absolute_path_to_file_name')

Ответ 4

Передайте итератору (например, результат open()) конструктору HttpResponse.

Ответ 5

Почему бы не вернуть HttpResponseRedirect в местоположение правильного статического файла?

Ответ 6

Обслуживание файлов непосредственно из представления происходит очень медленно. Если вы ищете обычную файловую службу, см. Этот вопрос: Наличие Django для загрузки файлов

Чтобы очень легко обслуживать файлы с помощью представления (например, для целей отладки), продолжайте чтение.

# In your urls.py:
url(r'^test-files/(?P<name>.+)/$', views.test_files, name='test_files'),

# In your views.py:
from django.http.response import HttpResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt # (Allows file download with POST requests, can be omitted)
def test_files(request, name):
    if name == "myxml":
        fsock = open("/djangopath/data/static/files/my.xml", "rb")
        return HttpResponse(fsock)

Это позволяет загрузить файл с: http://127.0.0.1:8080/app/test-files/myxml/

Ответ 7

Нельзя использовать django для обслуживания статического контента (не говоря уже, на несколько порядков медленнее).

Я предпочел бы преобразовать представление в процессор контекста и использовать переменные в шаблонах, чтобы найти, какие блоки включать.