在 root 的子文件夹中使用 Django 项目和静态文件

Using a Django project and static files in a subfolder of root

我最近将一个 Django 项目部署到我的 DigitalOcean Droplet。我需要在 root 的子文件夹中访问它(即 www.domainname.com/)。到目前为止,这可以在 apache 配置文件中使用 WSGI 别名。不过,我在提供静态 js 文件时遇到问题。

我在模板中使用 {% static %} 标签来执行此操作。然而,当我在浏览器中检查它们时,我的 js 文件似乎总是被当前页面的 html 替换。这是我在 settings.py:

中的静态相关设置
STATIC_URL = '/static/'
STATIC_ROOT = '/var/www/html/<project name>/static'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "/static"),
]

更新 1

这是我的 Apache 配置:

在sites-available/default中:

<Directory /var/www/>
       Options Indexes FollowSymLinks MultiViews
       AllowOverride All
       Order allow,deny
       allow from all
</Directory>

<VirtualHost <project name>:8000>
    ServerName <project name>
    ServerAlias <domain>/<project name>
    ServerAdmin <email>

    DocumentRoot /var/www/html/<project name>
    WSGIScriptAlias /<project name>/ /var/www/html/<project name>/<project name>/wsgi.py

    ErrorLog /var/www/html/logs/error.log
    CustomLog /var/www/html/logs/custom.log combined
    WSGIPythonPath /var/www/html/<project name>
</VirtualHost>

在apache2.conf中:

WSGIScriptAlias /<project name> /var/www/html/<project name>/<project name>/wsgi.py
WSGIPythonPath /var/www/html/<project name>

<Directory /var/www/html/<project name>>
   <Files wsgi.py>
       Require all granted
   </Files>
</Directory>

更新 2

似乎正在通过将静态路径附加到当前页面的路径来请求 .js 文件,即

<domain name>.com/<project name>/<app name>/<page>/<project name>/static/js/<js file name>

您的 Apache 配置中需要一个 Alias directive,以便为您的静态文件提供服务。

与在提供之前通过 Django 视图呈现的模板不同,静态文件通常由 Web 服务器(或某些单独的服务)直接提供以提高性能。毕竟你通常只需要文件本身,所以 Django 所需的开销是不必要的。这在 Django 的文档 here.

中进行了讨论

没有Alias指令,请求被传递给Django处理。 Django 改变了 Apache 的默认行为,从直接从 DocumentRoot 提供文件,到将 URL 映射到视图,然后构建响应。因此,根据您的 urls.py 安排,静态文件请求可能会导致 404 页面或来自匹配视图的响应(您看到的 HTML)。

要解决这个问题,您可以添加

Alias /static/ /var/www/html/<project name>/static/

到配置文件中的虚拟主机。当在以 /static/.

开头的 URI 发出请求时,这将告诉 Apache 从您的静态目录提供文件

例如,/static/index.js 的 URI 将导致 Apache 将文件 /var/www/html/<project name>/static/index.js 作为响应提供。


此外,您的 VirtualHost 中有一个错误。您提供的地址是 <project name>,这不是一个有效的选项 (see here)。虚拟主机地址必须是 IP 地址、域名或通配符 *

因为 <project name> 是其中的 none,所以虚拟主机不匹配任何东西,并且不应用其中的配置。我建议通过更改

来修复它
<VirtualHost <project name>:8000>

<VirtualHost *:8000>

它将匹配请求所期望的任何主机。