[英]Read static file in view
为了集成Django
和Ember
,我决定在Django
视图中提供我的Ember SPA
(避免CORS
问题,只为前端和API提供一台服务器,等等)。 我这样做是这样的:
# 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
是静态资产的一部分。 在开发中,这很容易:
Django
应用程序可以直接访问index.html
但是在生产中,事情变得更加复杂,因为静态资产不是django应用程序本地的,而是可以在Amazon S3上访问的。 我为此使用django-storages
。
无论使用什么后端来存储/服务静态文件,如何以一种通用方式从视图中读取静态文件的内容?
首先,我认为您的做法不是一个好主意。
但是,要回答您的问题:在您的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,与您的static /文件,robots.txt,favicon.ico等相同。而不是通过Django。 网络服务器速度更快,使用适当的缓存,在Nginx或Apache设置中仅使用一行,而不是Django中的整个视图功能。
这是我目前的解决方案。 在开发中有效,尚不确定生产(您需要提交未经测试的代码来验证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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.