Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Not Applying CSS File From App on 404 Page

Django 3.0.8

Python 3.7.x

I've got a Django project with a few apps. I'm trying to make some 'default' error pages for like 400, 403, 404, 500 errors. I've done that and the appropriate templates display - but without any styling or JS.

In the 404 error page, I'm trying to link to the CSS from one of the apps so the correct styling gets applied - but in the console, I see this error:

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.

The file exists there, however.

That particular CSS file lives in two places: in the app directory and it also lives in the STATIC_ROOT because I ran the python manage.py collectstatic command.

The STATIC_URL is set to /static/

The CSS file is located at:

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

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

My 404 template lives at:

project_dir/templates/404.html

My link to the CSS looks like this:

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

My project URL's look like this:

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
)

I've tried a lot of different solutions (like getting rid of comments in the CSS or changing the type in the HTML link) but nothing has worked thus far.

What is the best way to accomplish this?

EDIT TO ADD: My 404.html page looks like this:

{% 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 %}

The JS files give 404 errors as well, but I figure once I find out the cause of the CSS issues, I can figure out the JS issues as well. The 'error_base.html' file is essentially a boilerplate HTML file with the appropriate blocks in the appropriate spots for the blocks listed in the 404.html page.

ADDITIONAL EDIT TO ADD :

My static files settings look like this:

# 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")

EDIT TO ADD: Tree structure looks like this:

├── 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
like image 973
Hanny Avatar asked Jan 25 '23 20:01

Hanny


1 Answers

TLDR:

If you want to serve static files with DEBUG=False using a local development server, you need to use the --insecure flag:

python manage.py runserver --insecure

Why you get the error:

Every time you render html in your browser, behind the scenes a request is made to fetch each of your static files. So in your case, the 404.html template is telling your browser to fetch http://127.0.0.1:8000/static/launcher/dist/css/launcher.css. If your django server doesn't know where that file is, it will respond with the 404.html template instead of the css, which has a MIME type of text/html, and not text/css, hence your error.

Why django can't find the css files:

If you look at the source code for the static function that you call in your urls.py, it looks something like this:

from django.conf.urls.static import static

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

    return [
        re_path(...)
    ]

Which means that the re_path that is used to render static files, is no longer there, since you set DEBUG=False to test your 404.html template...

Credit to Dmitry Shevchenko for the shortcut.

like image 68
Lord Elrond Avatar answered Jan 27 '23 10:01

Lord Elrond