在视图中读取静态文件

时间:2016-01-02 09:52:28

标签: django ember.js static-files django-storage

为了整合setStringResource(string.xml-ar)Django,我决定在Ember视图中投放Ember SPA(避免Django个问题,只有一个服务器用于前端和API等)。我是这样做的:

CORS

# urls.py urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^api/', include(api_urls, namespace='api')), ... url(r'^$', views.emberapp, name='emberapp'), ... ] # views.py from django.http import HttpResponse def emberapp(request): # The Ember frontend SPA index file # This only works in development, and is anyway hacky EMBER_FE_INDEX_HTML = '/absolute/path/to/my/frontend/static/fe-dist/index.html' template_file = open(EMBER_FE_INDEX_HTML) html_content = index_file.read() index_file.close() return HttpResponse(html_content) 是静态资产的一部分。在开发过程中,这很容易:

  • index.html可直接访问文件系统中的index.html应用程序
  • 我知道索引文件的绝对路径

但是在生产环境中事情更复杂,因为静态资产不是django应用程序的本地资产,而是可以在Amazon S3上访问。我使用Django

无论使用哪个后端存储/提供静态文件,如何以通用方式从视图中读取静态文件的内容?

2 个答案:

答案 0 :(得分:1)

首先,我不认为你这样做是个好主意。

但是,回答你的问题:在你的settings.py中,你可能已经定义了Django将收集所有静态文件的目录。

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

因此,在您看来,您只需要获取文件os.path.join(settings.STATIC_ROOT, 'index.html')

也就是说,您应该通过网络服务器提供index.html,与静态/文件,robots.txt,favicon.ico等相同。不是通过Django。 Web服务器速度更快,使用正确的缓存,在Nginx或Apache设置中只有一行,而不是Django中的整个视图函数。

答案 1 :(得分:0)

这是我目前的解决方案。在开发中工作,还不确定生产(你需要提交未经测试的代码以验证Heroku中与生产相关的代码,这是一种痛苦)

from django.conf import settings
from django.http import HttpResponse
from django.core.files.storage import get_storage_class

FE_INDEX_HTML = 'fe/index.html'  # relative to the collectstatic directory


def emberapp(request):
    # The Ember frontend SPA index file
    # By getting the storage_class like this, we guarantee that this will work
    #   no matter what backend is used for serving static files
    #   Which means, this will work both in development and production
    #   Make sure to run collectstatic (even in development)
    # TODO: how to use this in development without being forced to run collectstatic?
    storage_class = get_storage_class(settings.STATICFILES_STORAGE)
    # TODO: reading from a storage backend can be slow if assets are in a third-party server (like Amazon S3)
    #   Maybe streaming the static file from the server would be faster?
    #   No redirect to the Amazon S3 asset, please, since the Ember App needs to
    #   run from the same URL as the API, otherwise you get CORS issues
    with storage_class().open(FE_VWORKS_INDEX_HTML) as index_file:
        html_content = index_file.read()
    return HttpResponse(html_content)

或者,回复一个StreamingHttpResponse,它不会强制Django读取内存中的整个文件(并等待它被读取):

def emberapp(request):
    # The Ember frontend SPA index file
    # By getting the storage_class like this, we guarantee that this will work
    #   no matter what backend is used for serving static files
    #   Which means, this will work both in development and production
    #   Make sure to run collectstatic (even in development)
    # TODO: how to use this in development without being forced to run collectstatic?
    storage_class = get_storage_class(settings.STATICFILES_STORAGE)
    index_file = storage_class().open(FE_INDEX_HTML)
    return StreamingHttpResponse(index_file)