Django没有在404页面上应用来自应用程序的CSS文件

Posted

技术标签:

【中文标题】Django没有在404页面上应用来自应用程序的CSS文件【英文标题】:Django Not Applying CSS File From App on 404 Page 【发布时间】:2020-11-16 20:56:45 【问题描述】:

Django 3.0.8

Python 3.7.x

我有一个包含一些应用程序的 Django 项目。我正在尝试为 400、403、404、500 错误创建一些“默认”错误页面。我已经完成了,并显示了相应的模板 - 但没有任何样式或 JS。

在 404 错误页面中,我尝试从其中一个应用程序链接到 CSS,以便应用正确的样式 - 但在控制台中,我看到此错误:

Refused to apply style from 'http://127.0.0.1:8000/static/launcher/dist/css/launcher.css' because of its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

该文件存在那里,但是。

那个特定的 CSS 文件位于两个位置:在 app 目录中,它也位于 STATIC_ROOT 中,因为我运行了 python manage.py collectstatic 命令。

STATIC_URL 设置为/static/

CSS 文件位于:

project_dir/launcher/static/launcher/dist/css/launcher.css

project_dir/static/launcher/dist/css/launcher.css

我的 404 模板位于:

project_dir/templates/404.html

我的 CSS 链接如下所示:

<link rel="stylesheet" type="text/css" href="% static 'launcher/dist/css/launcher.css' %" />

我的项目 URL 如下所示:

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("launcher.urls")),
    path("app2/", include("app2.urls")),
    path("app3/", include("app3.urls")),
    path(
        "robots.txt",
        TemplateView.as_view(
            template_name="robots.txt", content_type="text/plain"
        ),
    ),
    path(
        "favicon.ico",
        RedirectView.as_view(
            url=staticfiles_storage.url("favicon.ico"), permanent=False
        ),
        name="favicon",
    ),
]
urlpatterns += static(
    settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
)
urlpatterns += static(
    settings.STATIC_URL, document_root=settings.STATIC_ROOT
)

我尝试了很多不同的解决方案(比如去掉 CSS 中的 cmets 或更改 HTML 链接中的类型),但到目前为止都没有奏效。

最好的方法是什么?

编辑添加:我的 404.html 页面如下所示:

% extends 'error_base.html' %
% load static %

% block css_imports %
    <link rel="stylesheet" type="text/css" href="%  static 'launcher/dist/css/launcher.css' %" />
% endblock %

% block script_imports %
    <script src="% static 'launcher/dist/js/vendors~main.f11c6fb90f8f72673956.js' %"></script>
    <script src="% static 'launcher/dist/js/main.dce999efa12cf745c86d.js' %"></script>
% endblock %

% block content %
    <h1>Whoops!</h1>
    404
    <h3>We are having some issue finding that particular item.</h3>
    <p>If you feel this was due to an error - please contact us!
    </p>
% endblock %

JS 文件也会出现 404 错误,但我认为一旦找出 CSS 问题的原因,我也可以找出 JS 问题。 “error_base.html”文件本质上是一个样板 HTML 文件,在 404.html 页面中列出的块的适当位置具有适当的块。

要添加的附加编辑:

我的静态文件设置如下所示:

# Static files (CSS, javascript, Images)
STATIC_URL = "/static/"

STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'launcher/static/'),
    os.path.join(BASE_DIR, 'app1/static/'),
    os.path.join(BASE_DIR, 'app2/static/'),
]

# Media files 
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

编辑添加:树结构如下所示:

├── README.md
├── project_dir
│   ├── __init__.py
│   ├── context_processors.py
│   ├── settings.py
│   ├── unit-test-settings.py
│   ├── urls.py
│   ├── utils.py
│   └── wsgi.py
├── geckodriver.log
├── app_1
   ├── static
   │   └── app_1
   │       ├── dist
   │       │   ├── css
   │       │   │   └── app_1.css
   │       │   └── js
   │       │       ├── main.f3eaca15a899d1a9d4e4.js
   │       │       └── vendors~main.48489b4c92919034fc8f.js
   │       ├── fa-grav.png
   │       ├── grav.png
   │       ├── grav_30.png
   │       └── src
   │           ├── css
   │           │   └── style.css
   │           ├── html
   │           │   └── webpack_bundles.html
   │           ├── js
   │           │   ├── index.js
   │           │   └── indellis_form.js
   │           └── scss
   │               └── app_1.scss
   └─ ....other standard app files
├── app_2
   ├── static
   │   └── app_2
   │       ├── dist
   │       │   ├── css
   │       │   │   └── app_2.css
   │       │   └── js
   │       │       ├── main.cedd2abecaa899d1a9d4e4.js
   │       │       └── vendors~main.48325ceds92919034fc8f.js
   │       ├── fa-grav.png
   │       ├── grav.png
   │       ├── grav_30.png
   │       └── src
   │           ├── css
   │           │   └── style.css
   │           ├── html
   │           │   └── webpack_bundles.html
   │           ├── js
   │           │   ├── index.js
   │           │   └── registration_form.js
   │           └── scss
   │               └── app_2.scss
   └─ ....other standard app files
├── launcher
│   ├── static
│   │   └── launcher
│   │       ├── dist
│   │       │   ├── css
│   │       │   │   └── launcher.css
│   │       │   └── js
│   │       │       ├── main.75ef788b0aea38c3c71b.js
│   │       │       └── vendors~main.d806da1f66faa822a6ef.js
│   │       └── src
│   │           ├── css
│   │           │   └── style.css
│   │           ├── html
│   │           │   └── webpack_bundles.html
│   │           ├── js
│   │           │   └── index.js
│   │           └── scss
│   │               └── launcher.scss
   └─ ....other standard app files
├── manage.py
├── pyproject.toml
├── pytest.ini
├── requirements.txt
├── setup.cfg
├── static
│   ├── app_1
│   │   ├── dist
│   │   │   ├── css
│   │   │   │   └── app_1.css
│   │   │   └── js
│   │   │       ├── main.f3eaca15a899d1a9d4e4.js
│   │   │       └── vendors~main.48489b4c92919034fc8f.js
│   │   ├── fa-grav.png
│   │   ├── grav.png
│   │   ├── grav_30.png
│   │   └── src
│   │       ├── css
│   │       │   └── style.css
│   │       ├── html
│   │       │   └── webpack_bundles.html
│   │       ├── js
│   │       │   ├── index.js
│   │       │   └── indellis_form.js
│   │       └── scss
│   │           └── app_1.scss
│   ├── project_dir
│   │   ├── favicon.ico
│   │   ├── icons
│   │   │   ├── android-chrome-144x144.png
│   │   │   ├── apple-touch-icon-120x120-precomposed.png
│   │   │   ├── apple-touch-icon-120x120.png
│   │   │   ├── apple-touch-icon-152x152-precomposed.png
│   │   │   ├── apple-touch-icon-152x152.png
│   │   │   ├── apple-touch-icon-180x180-precomposed.png
│   │   │   ├── apple-touch-icon-180x180.png
│   │   │   ├── apple-touch-icon-60x60-precomposed.png
│   │   │   ├── apple-touch-icon-60x60.png
│   │   │   ├── apple-touch-icon-76x76-precomposed.png
│   │   │   ├── apple-touch-icon-76x76.png
│   │   │   ├── apple-touch-icon-precomposed.png
│   │   │   ├── apple-touch-icon.png
│   │   │   ├── browserconfig.xml
│   │   │   ├── favicon-16x16.png
│   │   │   ├── favicon-32x32.png
│   │   │   ├── mstile-144x144.png
│   │   │   ├── mstile-150x150.png
│   │   │   ├── safari-pinned-tab.svg
│   │   │   └── site.webmanifest
│   │   └── proj_icon.ico
│   ├── launcher
│   │   ├── dist
│   │   │   ├── css
│   │   │   │   └── launcher.css
│   │   │   └── js
│   │   │       ├── main.75ef788b0aea38c3c71b.js
│   │   │       └── vendors~main.d806da1f66faa822a6ef.js
│   │   └── src
│   │       ├── css
│   │       │   └── style.css
│   │       ├── html
│   │       │   └── webpack_bundles.html
│   │       ├── js
│   │       │   └── index.js
│   │       └── scss
│   │           └── launcher.scss
│   ├── app_2
│   │   ├── dist
│   │   │   ├── css
│   │   │   │   └── app_2.css
│   │   │   └── js
│   │   │       ├── main.cedd2abecaa899d1a9d4e4.js
│   │   │       └── vendors~main.48325ceds92919034fc8f.js
│   │   ├── fa-pdf.png
│   │   ├── id_card_30.png
│   │   ├── rc-u.png
│   │   ├── rg.png
│   │   └── src
│   │       ├── css
│   │       │   └── style.css
│   │       ├── html
│   │       │   └── webpack_bundles.html
│   │       ├── js
│   │       │   └── index.js
│   │       └── scss
│   │           └── app_2.scss
├── templates
│   ├── 400.html
│   ├── 403.html
│   ├── 404.html
│   ├── 500.html
│   ├── base.html
│   ├── error_base.html
│   └── robots.txt

【问题讨论】:

所以这就是错误的原因。必须与您的静态配置有关。现在,您在服务器控制台中看到什么了吗?你能访问其他静态文件吗? @YuriNudelman 由于某种原因,我无法直接从浏览器访问任何静态文件。我也用我的静态信息更新了我的设置。 【参考方案1】:

TLDR:

如果您想使用本地开发服务器通过 DEBUG=False 提供静态文件,则需要使用 --insecure 标志:

python manage.py runserver --insecure

为什么会出现错误:

每次在浏览器中呈现 html 时,都会在后台发出请求以获取每个静态文件。因此,在您的情况下,404.html 模板告诉您的浏览器获取http://127.0.0.1:8000/static/launcher/dist/css/launcher.css。如果您的 django 服务器不知道该文件在哪里,它将使用 404.html 模板而不是 css 进行响应,该 css 的 MIME 类型为 text/html ,而不是 text/css,因此是您的错误。

django为什么找不到css文件:

如果您查看您在 urls.py 中调用的 static 函数的源代码,它看起来像这样:

from django.conf.urls.static import static

def static(...):
    if not settings.DEBUG:
        return []

    return [
        re_path(...)
    ]

这意味着用于渲染静态文件的 re_path 不再存在,因为您设置了 DEBUG=False 来测试您的 @ 987654334@ 模板...

感谢Dmitry Shevchenko 的快捷方式。

【讨论】:

与默认的 django 内置方法相比,使用“静态”方法是否有负面影响? @Hanny See Why does DEBUG=False setting make my django Static Files Access fail?. @Hanny 你不应该在生产中使用这种方法。相反,静态文件应该由您的服务器(nginx、Apache 等)处理【参考方案2】:

这通常意味着页面找不到您的 css 文件,并试图加载您未找到的页面,即 html。

尝试对错误页面上的链接使用完整的绝对路径,看看是否可行:

<link rel="stylesheet" type="text/css" href="/static/launcher/dist/css/launcher.css"/>

如果可行,那么接下来我将检查以确保 Django 正在替换的 static 变量实际上在运行时设置正确。我怀疑路径有点偏离。

如果这不起作用,请尝试应用程序文件夹中 css 文件的完整绝对路径,而不是 STATIC_ROOT

<link rel="stylesheet" type="text/css" href="/launcher/static/launcher/dist/css/launcher.css"/>

如果这有效而第一个无效,那么当您的文件被收集到STATIC_ROOT 时,我会怀疑配置/翻译中的某个地方存在问题。我不熟悉这个过程,所以我不确定哪些内容被移动到哪里以及哪些元数据被更改(如果有的话)。我想没有人会这样做,但唯一确定的方法就是尝试一下。

更新:

您的 STATICFILES_DIRS 似乎没有指向 css 文件实际所在的最终文件夹。完成这些路径,它可能会起作用(添加 dist/static... 等)

【讨论】:

【参考方案3】:

我本来想写评论,但由于声誉问题,我不能,因为我是新人。您应该尝试在浏览器中访问链接 (http://127.0.0.1:8000/static/launcher/dist/css/launcher.css)!如果css文件没有打开路径就是问题。

另一个可能的原因是css文件开头的注释。

【讨论】:

以上是关于Django没有在404页面上应用来自应用程序的CSS文件的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 网站上找不到页面 404?

Django 仅提供索引页面,其他所有页面为 404

使用 Django + react-router 找不到 404 页面

在 django 上运行的 Python Web 应用程序,cPanel 显示错误:找不到页面

Django 1.11 404 页面,而 Debug=True

Django 404页面未加载