【问题标题】:how to make django serve non static js files?如何让 django 提供非静态 js 文件?
【发布时间】:2020-01-09 13:48:26
【问题描述】:

我的 python 后端服务器将 react 应用程序作为静态文件提供服务。 在反应中,当我们构建应用程序时,src 目录中的所有内容都被捆绑在一起,但是,src 之外有一个 javascript 文件,在 public 目录中,我把它留在那里,因为我想在构建后保持不变。我这样做的原因是因为在 src 代码中,我创建了 Workers,并且要创建 worker,我们必须指定 worker 文件的 url。这个文件叫做worker.js,构建后保持不变,但是部署后端后,前端无法访问/worker.js url,因为显然django只提供静态文件,所以/worker.js无法识别并且索引.html 改为返回。如何才能访问这个非静态的 js 文件?

【问题讨论】:

  • 我不明白。 “静态”的定义是文件按原样提供给您的浏览器,而动态的响应是计算/构造(django视图所做的)。所以你如何描述它,“worker.js”只是另一个静态文件。 “django 只提供静态文件”也是不正确的,实际上 django 根本不应该提供静态文件,除非在开发模式下。
  • 您可以将您的静态文件(包括worker.js)放在您想要的任何目录中。如果它位于您的一个 django 应用程序内的 static/ 目录中,django 会找到它,只需确保访问它的 url 以您的 STATIC_URL 为前缀。如果它在您项目的任何其他目录中,将该目录添加到 STATICFILES_DIRS 以便 django 可以找到它。在开发中就是这样。在生产中,在您 collectstatic 之后,您的所有静态文件都被复制到 STATIC_ROOT 中,您需要确保您的 Web 服务器 (apache/nginx) 找到它们(因为 Django 不提供静态文件) .
  • “只要确保访问它的 url 以你的 STATIC_URL 为前缀”你能澄清一下吗?
  • 好吧,既然worker.js 是一个静态文件,需要用“/static/”开头的url来获取它(假设STATIC_URL =“/static/”) ,例如“/static/root-js/worker.js”。 “root-js/”是放置 worker.js 的静态目录之一中的文件夹(您可以随意命名,它不能与其他静态文件夹中的其他文件夹冲突)并且可以是另一个文件夹而不是 where你还有其他的 js 文件。
  • 对。然后发生的事情是 webpack 构建生成了一个“静态”文件夹和其他未捆绑的文件。我的 STATIC-ROOT 是这个静态文件夹,所以其他文件被忽略了。我可以将静态文件夹及其父文件夹都添加为 STATICFILES_DIRS 还是会发生冲突?我不想一直在静态文件夹中手动添加worker.js

标签: python django reactjs webpack create-react-app


【解决方案1】:

静态文件如何工作的解释:

发展

让我们首先让它在开发环境中工作(django 使用 runserver 为您的静态文件提供服务)。 STATIC_ROOT 在这种情况下不相关。

Django 可以从这些位置找到你所有的静态文件:

  • 位于您的应用程序内的任何 /static/ 文件夹,例如如果您有 blog 应用程序,则将解析文件夹 /blog/static/
  • STATICFILES_DIRS 中指定的任何文件夹,例如,如果您的主项目中有一个assets 文件夹,您可以使用os.path.join(BASE_DIR, "assets") 将其添加到STATICFILES_DIRS,其中BASE_DIRmanage.py.

如果blog 应用程序和您的资产目录都需要“logo.png”怎么办?不用担心图像、js 文件、css 文件有唯一的名称,使用命名空间。在blog 应用程序中,将所有静态文件放在/blog/static/blog/ 中,因此在使用它们时您需要参考/blog/logo.png,并且您肯定知道它会是正确的logo.png。在主项目中,将文件放入assets/assets(或改为static/assets),以便您可以参考/assets/logo.png 了解项目的主要资产。

现在如果你设置STATIC_URL = "/static/",这告诉django所有静态文件的url都以“/static/”为前缀,即上面的logo可以用“/static/assets/logo.png”和“/static”来检索/博客/logo.png”。这是必需的,因为它允许将静态文件的 url 与 Django 路由到视图的 url 区分开来。

实际上,在您的模板中,您将使用{% static 'blog/logo.png' %},因此您不必在任何地方硬编码STATIC_URL

现在进入 webpack。它需要将其包资产放在上述任何目录中,或者放在它自己的目录中,您**也添加到STATICFILES_DIRS。让我们假设后者:我们的项目中还有一个/webpack/webpack/ 文件夹,它在STATICFILES_DIRS 中定义,所以所有的webpack 资产都将通过url 前缀“/static/webpack/”访问。

worker.js 文件应该在“assets/assets”和您的其他脚本中,如果您通过 url 引用它(通过 HTTP 请求获取它),您应该通过“/static/assets”引用它/worker.js" 或使用相对 URL "../assets/worker.js"。

生产

部署后,您不再使用 Django 提供静态文件,而是使用网络服务器,例如阿帕奇或 Nginx。您将 Web 服务器配置为识别以 STATIC_URL ("/static/") 开头的任何请求,并从 STATIC_ROOT 获取相应的文件。

因此,首先要做的是将 django 应用程序的所有静态文件复制到 Web 服务器可访问的文件夹/位置。该位置在您的项目文件夹之外

设置STATIC_ROOT = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(BASE_DIR)), 'static')),将其指向项目父文件夹中的“静态”目录。

然后运行python manage.py collectstatic

这会将所有静态文件复制到项目外部的这个新静态文件夹中。你会看到:

path/to/dir/
   |_ static/
   |   |_ blog/
   |   |   |_ logo.png
   |   |_ assets/
   |   |   |_ logo.png
   |   |   |_ worker.js
   |   |_ webpack/
   |       |_ some_file.js
   |_ django_project/
       |_ manage.py
       |_ main_app/
       |    |_ settings.py
       |_ assets/
       |    |_ assets/
       |        |_ worker.js
       |_ blog/
       |   |_ static/
       |       |_ blog/
       ...

现在,当您的网络服务器看到“/static/assets/worker.js”网址时,它会返回“path/to/dir/static/assets/worker.js”中的文件。

如果你让你的生产服务器构建 webpack 文件而不是将它们提交到你的源(即它们不在“django_project”中),那么你应该配置 webpack 将它们放在正确的位置“path/to/dir/ static/webpack/" 因为那是您的网络服务器将在其中寻找它们的地方。

想象一下,现在您将所有内容都转移到了第三方存储提供商。然后你只需要做两件事:

  • 为该存储提供程序安装和配置存储后端,以便 Django 知道如何在那里读取/写入文件(使用collecstatic)。这可能包括设置STATIC_ROOT,例如STATIC_ROOT = https://my-bucket.my-storage-provider.com/static.
  • STATIC_URL 设置为存储提供者的URL,例如STATIC_URL = https://my-bucket.some_cdn.com/。在这里,我们指向您已配置为知道从何处获取文件的 CDN。

就是这样,一切都在继续工作。

【讨论】:

    猜你喜欢
    • 2012-09-29
    • 2014-07-25
    • 1970-01-01
    • 2014-02-26
    • 2014-12-22
    • 2021-07-08
    • 2012-12-16
    • 1970-01-01
    相关资源
    最近更新 更多