Мне нужно вернуть файлы css и js файлы в соответствии с определенной логикой. Ясно, что статическая подача не выполняет то, что мне нужно. У меня есть представление, метод визуализации которого использует логику для поиска нужного файла, но тогда я должен вернуть его. Технически я могу просто прочитать файл и добавить его в объект HttpResponse с соответствующим типом mime, но мне было интересно, есть ли лучшая стратегия. (например, fpassthru() в php)
Как вернуть статические файлы, проходящие через представление в django?
Ответ 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 для обслуживания статического контента (не говоря уже, на несколько порядков медленнее).
Я предпочел бы преобразовать представление в процессор контекста и использовать переменные в шаблонах, чтобы найти, какие блоки включать.