Как вернуть статические файлы, проходящие через представление в django? - PullRequest
18 голосов
/ 19 февраля 2010

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

Ответы [ 7 ]

20 голосов
/ 03 августа 2010

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

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
9 голосов
/ 20 февраля 2010

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

По крайней мере для Apache и NginX есть модуль, позволяющий использовать HTTP-заголовок X-SendFile.На сайте 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

6 голосов
/ 22 декабря 2011

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

from django.contrib.staticfiles.views import serve

...
def view_function(request):
   return serve(request, 'absolute_path_to_file_name')
1 голос
/ 03 февраля 2016

Работа с файлами напрямую из представления очень медленная. Если вам нужна обычная система хранения файлов, посмотрите этот вопрос: Наличие в 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/

1 голос
/ 19 февраля 2010

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

1 голос
/ 19 февраля 2010

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

0 голосов
/ 19 февраля 2010

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

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

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