如何返回通过django中的视图的静态文件?

时间:2010-02-19 06:36:25

标签: django

我需要根据特定逻辑返回css文件和js文件。显然,静态服务并不能满足我的需求。我有一个视图,其render方法使用逻辑来查找正确的文件,但后来我必须返回它。从技术上讲,我可以只读取文件并将其填充到具有适当mime类型的HttpResponse对象中,但我想知道是否有更好的策略。 (比如php中的fpassthru())

9 个答案:

答案 0 :(得分:20)

这就是我使用的:

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

答案 1 :(得分:9)

您使用的是哪种网络服务器软件?

至少对于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

答案 2 :(得分:6)

为什么不在视图中使用Django静态文件

from django.contrib.staticfiles.views import serve

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

答案 3 :(得分:1)

将迭代器(例如open()的结果)传递给HttpResponse构造函数。

答案 4 :(得分:1)

为什么不将HttpResponseRedirect返回到正确的静态文件的位置?

答案 5 :(得分:1)

直接从视图提供文件非常慢。如果您正在寻找正常的文件服务,请参阅此问题:Having Django serve downloadable files

通过视图非常容易地提供文件(例如,出于调试目的)继续阅读。

# 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/

答案 6 :(得分:0)

您可以在视图中使用以下代码:
注意:在该函数中,我返回图像,但是您可以根据需要返回所有内容并设置context_type

from django.http import HttpResponse,Http404
import os

def img_finder(request, img_name):
    try:
        with open(os.path.dirname(os.path.abspath(__file__)) + '/static/img/' + img_name, 'rb') as f:
            return HttpResponse(f.read(), content_type="image/jpeg")
    except IOError:
        raise Http404

答案 7 :(得分:0)

这是最简单有效的方法。

app/urls.py

from django.urls import re_path
from app import views

urlpatterns = [
    re_path(r'^(?P<public_url>.*)$', views.public, name="public"),
]

app/views.py

import os
from django.conf import settings
from django.views.static import serve

def public(request, public_url):
    public_folder = os.path.join(str(settings.BASE_DIR), 'folder_path')
    return serve(request, public_url, document_root=public_folder)

答案 8 :(得分:-1)

使用django来提供静态内容应该是浪费(更不用说,慢几个数量级)。

我宁愿将视图转换为上下文处理器,并使用模板中的变量来查找要包含的块。