如何使用django提供静态文件,该文件在Heroku / OpenShift / etc上具有硬编码的相对路径? [英] How to serve static files with django that has hardcoded relative paths on Heroku/OpenShift/etc?

查看:217
本文介绍了如何使用django提供静态文件,该文件在Heroku / OpenShift / etc上具有硬编码的相对路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个第三方(我无法控制)提供的HTML / JS / CSS文件,它作为与使用Django和django-rest-framework构建的后端进行通信的单一页面应用程序。

I have HTML/JS/CSS files provided by a third party (whom I have no control over) that serves as a single page app that communicates with a backend built with Django and django-rest-framework.

我想在Heroku上托管这个,因此这些静态资产正由Django提供。这些文件包含彼此的相对路径。例如,index.html包含:

I'm wanting to host this on Heroku and thus these static assets are being served by Django. These files contains relative paths to each other. For example, the index.html contains:

<link rel="stylesheet" type="text/css" media="screen" href="styles/css/bootstrap.min.css">

导致404,因为 styles / css / bootstrap.min.css 不被django路由。

Which leads to a 404 because styles/css/bootstrap.min.css is not routed by django.

我知道从我的域根服务index.html的唯一方式 www.domain.com 有一个url配置,如:

The only way I know of to serve the index.html from my domain root www.domain.com is with an url config like:

url(r'^$', TemplateView.as_view(template_name='index.html'), name='home'),

...即使它不是真正的模板,它只是纯HTML。

...even though it's not really a template, it's just plain HTML.

问题起因于其他资产中的所有网址都相对于此 index.html 当然,Django不能这样工作。如果我正在开发这个前端应用程序,我将使用 static 模板标签,并将各种方法之一用于获取URL。

The problem arises from the fact that all the urls in the other assets are relative to this index.html and of course Django doesn't work like that. If I was developing this front-end application I'd be using the static template tag and one of the various ways to get urls to javascript.

我不介意从Heroku转换到另一个PaaS,如果他们提供了一个解决这个问题的解决方案,但手动编辑所有这些文件听起来不是一个有趣的工作...特别是考虑到我将会收到这些文件的更新。

I don't mind switching from Heroku to another PaaS if they offer a solution to this problem, but manually editing all these files does not sound like a fun job...especially considering the fact that I'll be receiving updates to these files going forward.

我认为在常规旧服务器上解决此问题的方法是配置网页服务器正确解析这些网址,但该选项在Heroku上似乎不可用。

I think the way to solve this on a regular old server would be to configure the web server to resolve these urls correctly, but that option doesn't seem to be available on Heroku.

推荐答案

以下是如何设置向Django提供静态文件和index.html,同时仍然可以使用Django视图进行管理信息中心,注册等。

Here's how to set up Django to serve your static files and index.html on / while still having the possibility to use Django views for the admin dashboard, registration etc.

from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.staticfiles.views import serve
from django.views.generic import RedirectView

admin.autodiscover()

urlpatterns = [

    # / routes to index.html
    url(r'^$', serve,
        kwargs={'path': 'index.html'}),

    # static files (*.css, *.js, *.jpg etc.) served on /
    # (assuming Django uses /static/ and /media/ for static/media urls)
    url(r'^(?!/?static/)(?!/?media/)(?P<path>.*\..*)$',
        RedirectView.as_view(url='/static/%(path)s', permanent=False)),

    # other views still work too
    url(r'^admin/', include(admin.site.urls)),
]

我指定 urlpatterns 作为列表,正如Django 1.10所要求的那样。从1.9开始,默认情况下,重定向是不永久的,因此您需要明确设置 permanent = True 如果您希望浏览器缓存这个,虽然在调试时我发现最好从 False 开始。

I specify urlpatterns as a list, as Django 1.10 requires. The redirects are not permanent by default since 1.9, so you need to explicitly set permanent=True if you want browsers to cache this, though when debugging I find it better to start with False.

此方法允许您使用创建反应应用程序 Yeoman 前端生成器,将一个内置的,最小化的前端应用程序打包成一个文件夹(如 dist / )。然后你就可以使用脚本将其移动到Django的静态文件文件夹(例如 myproject / static / )中,并从Heroku提供。

This approach allows you to use something like create-react-app or Yeoman frontend generators that package a built, minified frontend app into a single folder (like dist/). You then e.g. use a script to move that into Django's static files folder (e.g. myproject/static/) and serve it from Heroku.

Ian写的关于想要使用像S3这样的静态文件,但是有时候你只需要简单的使用一个存储库,一个Heroku dyno就可以使用Django + a SPA。另外,使用像 WhiteNoise 这样的东西,使Python的静态文件很好,可以让你
稍后轻松放入CDN 在您的静态文件前面。

What Ian wrote about wanting to use something like S3 for your static files stands, but sometimes you just want to start simple with one repository, one Heroku dyno and still be able to use Django + a SPA. Also, using something like WhiteNoise makes serving static files from Python pretty OK and allows you to later on easily put a CDN in front of your static files.

注意:对于用户上传的文件,您应该仍然使用外部服务,如Amazon S3或Backblaze B2(这是整合的4行代码)。

Note: for user-uploaded files you should still use an outside service like Amazon S3 or Backblaze B2 (which is 4 lines of code to integrate).


提供媒体文件



WhiteNoise不适合为用户上传的媒体文件提供服务。一方面,如上所述,它仅在启动时检查静态文件,因此在应用启动后添加的文件将不会被看到。更重要的是,从与主应用程序相同的域提供用户上传的文件是一个安全风险(这篇博客文章从Google安全性描述了这个问题)。除此之外,使用本地磁盘存储和提供用户媒体使得在多台机器上扩展应用程序变得更加困难。

Serving Media Files

WhiteNoise is not suitable for serving user-uploaded "media" files. For one thing, as described above, it only checks for static files at startup and so files added after the app starts won’t be seen. More importantly though, serving user-uploaded files from the same domain as your main application is a security risk (this blog post from Google security describes the problem well). And in addition to that, using local disk to store and serve your user media makes it harder to scale your application across multiple machines.

由于所有这些原因,更好将文件存储在单独的专用存储服务中,并将它们从那里提供给用户。 django-storages 库提供了许多选项,例如Amazon S3,Azure Storage和Rackspace CloudFiles。

For all these reasons, it’s much better to store files on a separate dedicated storage service and serve them to users from there. The django-storages library provides many options e.g. Amazon S3, Azure Storage, and Rackspace CloudFiles.

注2: c> DEBUG = False 有问题,请查看这个WhiteNoise问题解决方案。

Note 2: on production with DEBUG=False there are issues, so check out this WhiteNoise issue for a solution.

注3: 将此答案变成博客文章 here

注4:自从写这个,我一直在调整解决方案的前端路由,所以我最终发布了一个新的 django-spa 适合从Django简单提供单页应用程序的包。

Note 4: since writing this, I've been tweaking the solution more and more for frontend routing, so I ended up releasing a new django-spa package suited for simple serving of single-page apps from Django.

这篇关于如何使用django提供静态文件,该文件在Heroku / OpenShift / etc上具有硬编码的相对路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆